Is it good to have 4 columns as the primary key?

I have in the Students database tables with PK Student_ID , a course with PK Course_ID .

And two tables for storing the feedback result for each course, the Questions table I saved in questions of feedback with PK question_ID and feedback with the table.

I am wondering if I can use 3 foreign keys in the feedback table ( Course_ID , Student_ID , question_ID ) using PK feedback_ID

I think it’s useful to have a result for each question or student or course, but I don’t know if 4 columns can be used as the main key and good or not.

+5
source share
2 answers

Since most people believe that the Primary Key is a Clustering Cluster, I am going to interpret your question as β€œGood or bad, to have 4 columns as a clustering key”.

The situation you are considering is related to a debate such as a discussion of cluster indexes and a surrogate key versus a natural key .

In this situation, I would like to consider the impact of a composite byte key of 12 bytes wide and a four-class clustering key (twice as much if you intend to use bigint ). My decision tree will look something like this:

  • Will we use Hekaton (OLTP in memory)?

    • Yes => composite key. Run away .

    • No => Good call, continue ...

  • How many rows will be in this table?

    • Tens of millions, maybe more! => surrogate key (possibly).

      • If the data length of each row will be variable, rather than a narrow => surrogate key.

      • If the length of the string data is fixed and narrow, and this will lead to optimal use of the page => continue ...

    • Less than this => continue ...

  • How will the feedback table be requested?

    • Various combinations and not always all course_id, student_Id, question_id => surrogate key.

      • In this case, you may need to have several supporting index combinations of course_id, student_Id, question_id for your queries. The clustering key is included in all non-clustered indexes, and the more, the more space / pages are required for each index entry. => surrogate key.
    • Almost always all three course_id, student_Id, question_id or almost always course_id or course_id, student_Id ; but not student_id without course_id , and not question_id without course_id, student_Id (zero or only a pair of nonclustered indexes in this table) => continue ...

  • Will a link to another table link to this table?

    • Yes: for example. Course instructors will be able to leave a comment or comment regarding the answer to the feedback question. => surrogate key.

    • Kind ... for example. The Audit / History table will track insert / update / delete rows in this table.

      • a surrogate key can make tracking changes less difficult to verify, and the audit table clustering key is likely to be a surrogate key, as well as a datetime or surrogate key or composite key, as well as a datetime or surrogate key.
    • No => Composite key is a smart option


Even if my first run of the aforementioned decision tree leads me to a composite key, I will probably start my project using a surrogate key because it is easier to get rid of (because it is not used) than to go back and add it and implement its use.

Just to clarify, I had cases where I discovered that a composite key was the best solution and reorganized the design to remove the surrogate key. I do not want to leave the impression that the surrogate key is always the best solution, even if it is a standard default for many designers (including me).


I would start with something like this:

 create table feedback ( feedback_id int not null identity(1,1) , course_id int not null , student_id int not null , question_id int not null , response_added datetime not null constraint df_feedback_response_added_gd default getdate() , response nvarchar(max) null , constraint pk_feedback primary key clustered (feedback_id) , constraint fk_feedback_course foreign key (course_id) references course(course_id) , constraint fk_feedback_students foreign key (student_id) references student(student_id) , constraint fk_feedback_question foreign key (question_id) references question(question_id) , constraint uq_feedback_course_student_question unique (course_id, student_Id, question_id) /* or create a unique index to use include() instead */ ); /* unique index that includes response */ create unique nonclustered index ux_feedback_course_student_question_covering on feedback (course_id, student_Id, question_id) include (response_added, response); 

Link:

+2
source

If Feedback_Id uniquely identifies the record, then its presence as the Primary Key should work fine. Including multiple columns in a PC may cause problems in the future.

Suppose you want to save other feedback data (e.g. comments). You want to define a table called FeedbackComment, which should have feedback as a parent. FK can only go to one or more columns for which a UNIQUE constraint is defined. Typically, a PC is the goal of a PC.

Of course, you can have all PK columns defined (feedback_id, course_id, etc.) in the child table, but this will complicate the join.

In addition, if you use some kind of ORM (i.e., Entity Framework) at the application service level, a single integer primary key may be useful (for example, to have common methods that retrieve an object based on an integer identifier).

As Gordon noted, there is nothing wrong with composite primary keys, but think about what you do with the table and don’t complicate your life when application extensions are to be made.

+3
source

Source: https://habr.com/ru/post/1261941/


All Articles