I am using SQL & Java Springboot.
In my design, content is stored in modules & content have quite a few different variations.
Content can only be designated to a single module, once content is created it cannot updated to another module because different admin users have separated access to different module moderation.
The way activities are stored is with a foreign key table between, eg. extra & module.
@OneToMany
@JoinTable(name="module_extras",
joinColumns = @JoinColumn(name="module_id"),
inverseJoinColumns = @JoinColumn(name = "extra_id")
)
private List<Extra> extras = new ArrayList<>();
Because it is stored this way, every time I want to get only extra or a list of only extra, (which is a quite common use case as I have a designated area for it) it must:
- Recursively loop to get each
extrarequested, temporarily convert it to a DTO. - Recursively loop over each
module, checking if theextrais contained inside it. - If it find the corresponding
extratomodule, appending themodule.codeto theextra-moduledto. - then reply with all the
extra-moduledtorequested.
Given it must loop this logic, for every module and for all content's inside module (when called for content sections independently), potentially many, many times to support users refreshing & interacting with content, this seems like it would be bad on performance & has a multiple points of potential failure / errors.
The alternate solution I am considering is adding a moduleCode column to each content, like extra and demolish the relationship.
1.While it would take more storage doing this ^, would performance be better from doing far less number of operations?
- Is the above solution against convention?
If anybody has any suggestions or thoughts that may be useful from your own experience it would be greatly appreciated.
Module Class:
@Data @NoArgsConstructor @AllArgsConstructor @Entity
@Table(name = "module")
public class Module {
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique=true)
private String code;
@Nullable
private String name;
@ManyToMany
@JoinTable(name="module_students",
joinColumns = @JoinColumn(name="module_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private Set<User> students = new HashSet<>();
@ManyToMany
@JoinTable(name="module_admins",
joinColumns = @JoinColumn(name="module_id"),
inverseJoinColumns = @JoinColumn(name = "user_id")
)
private Set<User> admins = new HashSet<>();
@OneToMany
@JoinTable(name="module_quizzes",
joinColumns = @JoinColumn(name="module_id"),
inverseJoinColumns = @JoinColumn(name = "quiz_id")
)
private List<Quiz> quizzes = new ArrayList<>();
@OneToMany
@JoinTable(name="module_hangmen",
joinColumns = @JoinColumn(name="module_id"),
inverseJoinColumns = @JoinColumn(name = "hangnman_id")
)
private List<Hangman> hangmen = new ArrayList<>();
@OneToMany
@JoinTable(name="module_extras",
joinColumns = @JoinColumn(name="module_id"),
inverseJoinColumns = @JoinColumn(name = "extra_id")
)
private List<Extra> extras = new ArrayList<>();
@OneToMany
@JoinTable(name="module_matches",
joinColumns = @JoinColumn(name="module_id"),
inverseJoinColumns = @JoinColumn(name = "match_id")
)
private List<Match> matches = new ArrayList<>();
@OneToMany
@JoinTable(name="module_feedbacks",
joinColumns = @JoinColumn(name="module_id"),
inverseJoinColumns = @JoinColumn(name = "feedback_id")
)
private List<Feedback> feedbacks = new ArrayList<>();
@OneToMany
@JoinTable(name="module_swipes",
joinColumns = @JoinColumn(name="module_id"),
inverseJoinColumns = @JoinColumn(name = "swipe_id")
)
private List<Swipe> swipes = new ArrayList<>();