How to model very flexible referencing relationships between many tables?












0














I have various different entity types in my database. For purposes of example, consider an IMDB database:




  • Movie

  • Person

  • Actor

  • Director

  • Translation

  • and 20 more tables


My application enables free-form many-many relationships between any of these entities.



What is a sane way to model this in a maintainable way?



Currently, my app uses a table with "a_id", "a_type", "b_id", "b_type". With the type identifying the table (e.g. "movie"). This means there is no referential integrity checking, which makes me uneasy.



What are the alternatives? The only one that comes to mind is to expand the linking table with a column for every other table. So I have a_movie_id, a_actor_id, a_director_id and b_movie_id, b_actor_id, b_director_id. However, while this preserves referential integrity, it feels strange (I have not seen such tables before) and I suspect it would be difficult for application code to process it (it would have to have a big if-statement to check what is actually referenced).



Thus I ask for your advice - is there a convenient industry standard way to model such flexible relationships?



My database engine is is SQL Server.










share|improve this question







New contributor




Sander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Instead of creating a table for each role like Director, Actor and so on you'd better create a table Staff with many-to-many relationchips to the Movie and a dictionnary with possible person's roles like Director, Actor, Operator...
    – Denis Rubashkin
    1 hour ago
















0














I have various different entity types in my database. For purposes of example, consider an IMDB database:




  • Movie

  • Person

  • Actor

  • Director

  • Translation

  • and 20 more tables


My application enables free-form many-many relationships between any of these entities.



What is a sane way to model this in a maintainable way?



Currently, my app uses a table with "a_id", "a_type", "b_id", "b_type". With the type identifying the table (e.g. "movie"). This means there is no referential integrity checking, which makes me uneasy.



What are the alternatives? The only one that comes to mind is to expand the linking table with a column for every other table. So I have a_movie_id, a_actor_id, a_director_id and b_movie_id, b_actor_id, b_director_id. However, while this preserves referential integrity, it feels strange (I have not seen such tables before) and I suspect it would be difficult for application code to process it (it would have to have a big if-statement to check what is actually referenced).



Thus I ask for your advice - is there a convenient industry standard way to model such flexible relationships?



My database engine is is SQL Server.










share|improve this question







New contributor




Sander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




















  • Instead of creating a table for each role like Director, Actor and so on you'd better create a table Staff with many-to-many relationchips to the Movie and a dictionnary with possible person's roles like Director, Actor, Operator...
    – Denis Rubashkin
    1 hour ago














0












0








0







I have various different entity types in my database. For purposes of example, consider an IMDB database:




  • Movie

  • Person

  • Actor

  • Director

  • Translation

  • and 20 more tables


My application enables free-form many-many relationships between any of these entities.



What is a sane way to model this in a maintainable way?



Currently, my app uses a table with "a_id", "a_type", "b_id", "b_type". With the type identifying the table (e.g. "movie"). This means there is no referential integrity checking, which makes me uneasy.



What are the alternatives? The only one that comes to mind is to expand the linking table with a column for every other table. So I have a_movie_id, a_actor_id, a_director_id and b_movie_id, b_actor_id, b_director_id. However, while this preserves referential integrity, it feels strange (I have not seen such tables before) and I suspect it would be difficult for application code to process it (it would have to have a big if-statement to check what is actually referenced).



Thus I ask for your advice - is there a convenient industry standard way to model such flexible relationships?



My database engine is is SQL Server.










share|improve this question







New contributor




Sander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











I have various different entity types in my database. For purposes of example, consider an IMDB database:




  • Movie

  • Person

  • Actor

  • Director

  • Translation

  • and 20 more tables


My application enables free-form many-many relationships between any of these entities.



What is a sane way to model this in a maintainable way?



Currently, my app uses a table with "a_id", "a_type", "b_id", "b_type". With the type identifying the table (e.g. "movie"). This means there is no referential integrity checking, which makes me uneasy.



What are the alternatives? The only one that comes to mind is to expand the linking table with a column for every other table. So I have a_movie_id, a_actor_id, a_director_id and b_movie_id, b_actor_id, b_director_id. However, while this preserves referential integrity, it feels strange (I have not seen such tables before) and I suspect it would be difficult for application code to process it (it would have to have a big if-statement to check what is actually referenced).



Thus I ask for your advice - is there a convenient industry standard way to model such flexible relationships?



My database engine is is SQL Server.







sql-server database-design schema referential-integrity






share|improve this question







New contributor




Sander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor




Sander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question






New contributor




Sander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 hours ago









SanderSander

1012




1012




New contributor




Sander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Sander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Sander is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • Instead of creating a table for each role like Director, Actor and so on you'd better create a table Staff with many-to-many relationchips to the Movie and a dictionnary with possible person's roles like Director, Actor, Operator...
    – Denis Rubashkin
    1 hour ago


















  • Instead of creating a table for each role like Director, Actor and so on you'd better create a table Staff with many-to-many relationchips to the Movie and a dictionnary with possible person's roles like Director, Actor, Operator...
    – Denis Rubashkin
    1 hour ago
















Instead of creating a table for each role like Director, Actor and so on you'd better create a table Staff with many-to-many relationchips to the Movie and a dictionnary with possible person's roles like Director, Actor, Operator...
– Denis Rubashkin
1 hour ago




Instead of creating a table for each role like Director, Actor and so on you'd better create a table Staff with many-to-many relationchips to the Movie and a dictionnary with possible person's roles like Director, Actor, Operator...
– Denis Rubashkin
1 hour ago










2 Answers
2






active

oldest

votes


















0














This is opinion-based. I wouldn’t try to suggest there’s a best-practice here.



If you have separate tables for actors, directors, movies, and have a generic EntityID column with separate EntityType column, you’ll always need to use dynamic SQL to query it, because until you know the type, you won’t know which table to join to.



Another option is to have a generic table of entities which contains the type. Your relationships table is then just two columns.



Then you have sparse columns in your entities table for all your properties, as directors have different attributes from movies.



And you index it well, so that you’re not trawling through all the actors when you want a list of movies. Filtered indexes can be particularly handy here, so that you have a dedicated index for movies which includes the movie-related columns.



Views can make querying easier too, but for traversing relationships you can use the generic table.






share|improve this answer





























    0














    I would suggest you look at Graph databases in SQL Server 2017 as a possible solution. You can use simple linking tables for many-to-many relationships, but if your relationships are more complex than that as you've stated, you might find Graph databases are better suited.



    Either way, I think you need to remove the single linking table solution as this is poor database design. Each many-to-many relationship between two entities should have a separate linking table.



    Link 1



    Link 2






    share|improve this answer





















      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "182"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });






      Sander is a new contributor. Be nice, and check out our Code of Conduct.










      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f226656%2fhow-to-model-very-flexible-referencing-relationships-between-many-tables%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      0














      This is opinion-based. I wouldn’t try to suggest there’s a best-practice here.



      If you have separate tables for actors, directors, movies, and have a generic EntityID column with separate EntityType column, you’ll always need to use dynamic SQL to query it, because until you know the type, you won’t know which table to join to.



      Another option is to have a generic table of entities which contains the type. Your relationships table is then just two columns.



      Then you have sparse columns in your entities table for all your properties, as directors have different attributes from movies.



      And you index it well, so that you’re not trawling through all the actors when you want a list of movies. Filtered indexes can be particularly handy here, so that you have a dedicated index for movies which includes the movie-related columns.



      Views can make querying easier too, but for traversing relationships you can use the generic table.






      share|improve this answer


























        0














        This is opinion-based. I wouldn’t try to suggest there’s a best-practice here.



        If you have separate tables for actors, directors, movies, and have a generic EntityID column with separate EntityType column, you’ll always need to use dynamic SQL to query it, because until you know the type, you won’t know which table to join to.



        Another option is to have a generic table of entities which contains the type. Your relationships table is then just two columns.



        Then you have sparse columns in your entities table for all your properties, as directors have different attributes from movies.



        And you index it well, so that you’re not trawling through all the actors when you want a list of movies. Filtered indexes can be particularly handy here, so that you have a dedicated index for movies which includes the movie-related columns.



        Views can make querying easier too, but for traversing relationships you can use the generic table.






        share|improve this answer
























          0












          0








          0






          This is opinion-based. I wouldn’t try to suggest there’s a best-practice here.



          If you have separate tables for actors, directors, movies, and have a generic EntityID column with separate EntityType column, you’ll always need to use dynamic SQL to query it, because until you know the type, you won’t know which table to join to.



          Another option is to have a generic table of entities which contains the type. Your relationships table is then just two columns.



          Then you have sparse columns in your entities table for all your properties, as directors have different attributes from movies.



          And you index it well, so that you’re not trawling through all the actors when you want a list of movies. Filtered indexes can be particularly handy here, so that you have a dedicated index for movies which includes the movie-related columns.



          Views can make querying easier too, but for traversing relationships you can use the generic table.






          share|improve this answer












          This is opinion-based. I wouldn’t try to suggest there’s a best-practice here.



          If you have separate tables for actors, directors, movies, and have a generic EntityID column with separate EntityType column, you’ll always need to use dynamic SQL to query it, because until you know the type, you won’t know which table to join to.



          Another option is to have a generic table of entities which contains the type. Your relationships table is then just two columns.



          Then you have sparse columns in your entities table for all your properties, as directors have different attributes from movies.



          And you index it well, so that you’re not trawling through all the actors when you want a list of movies. Filtered indexes can be particularly handy here, so that you have a dedicated index for movies which includes the movie-related columns.



          Views can make querying easier too, but for traversing relationships you can use the generic table.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 1 hour ago









          Rob FarleyRob Farley

          13.7k12448




          13.7k12448

























              0














              I would suggest you look at Graph databases in SQL Server 2017 as a possible solution. You can use simple linking tables for many-to-many relationships, but if your relationships are more complex than that as you've stated, you might find Graph databases are better suited.



              Either way, I think you need to remove the single linking table solution as this is poor database design. Each many-to-many relationship between two entities should have a separate linking table.



              Link 1



              Link 2






              share|improve this answer


























                0














                I would suggest you look at Graph databases in SQL Server 2017 as a possible solution. You can use simple linking tables for many-to-many relationships, but if your relationships are more complex than that as you've stated, you might find Graph databases are better suited.



                Either way, I think you need to remove the single linking table solution as this is poor database design. Each many-to-many relationship between two entities should have a separate linking table.



                Link 1



                Link 2






                share|improve this answer
























                  0












                  0








                  0






                  I would suggest you look at Graph databases in SQL Server 2017 as a possible solution. You can use simple linking tables for many-to-many relationships, but if your relationships are more complex than that as you've stated, you might find Graph databases are better suited.



                  Either way, I think you need to remove the single linking table solution as this is poor database design. Each many-to-many relationship between two entities should have a separate linking table.



                  Link 1



                  Link 2






                  share|improve this answer












                  I would suggest you look at Graph databases in SQL Server 2017 as a possible solution. You can use simple linking tables for many-to-many relationships, but if your relationships are more complex than that as you've stated, you might find Graph databases are better suited.



                  Either way, I think you need to remove the single linking table solution as this is poor database design. Each many-to-many relationship between two entities should have a separate linking table.



                  Link 1



                  Link 2







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 40 mins ago









                  HandyDHandyD

                  56415




                  56415






















                      Sander is a new contributor. Be nice, and check out our Code of Conduct.










                      draft saved

                      draft discarded


















                      Sander is a new contributor. Be nice, and check out our Code of Conduct.













                      Sander is a new contributor. Be nice, and check out our Code of Conduct.












                      Sander is a new contributor. Be nice, and check out our Code of Conduct.
















                      Thanks for contributing an answer to Database Administrators Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.





                      Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                      Please pay close attention to the following guidance:


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f226656%2fhow-to-model-very-flexible-referencing-relationships-between-many-tables%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Liste der Baudenkmale in Friedland (Mecklenburg)

                      Single-Malt-Whisky

                      Czorneboh