在專案開發中往往會遇到兩個實體物件之間存在多對多關係的情況,此時我們會維護兩個實體物件表,乙個關係表,用來存放兩者之間的關係。比較典型的案例是學生表、課程表、學生課程關係表。在這種關係表中,我們可以確定的是,學生和課程關係雖然是多對多,但乙個確定的學生id和乙個確定的課程id在關係表中只能存在乙個。如下圖所示:,業務邏輯就是乙個學生只能有當前課程的乙個分數。
因此可以得知,通過student_id和course_id可以唯一確認乙個t_student_course_rel資料,相同的student_id、course_id最多只能存在一條資料。按照正常的業務邏輯來說,不會出現意外的情況,但是一旦出現了,對於以後的查詢操作將是乙個潛在的隱患,如 select * from t_student_course_rel where student_id=1 and course_id = 2 ,此時我們希望只查出來一條資料,但如果出現了意外情況,則可能對應出來多條資料,這樣便會報錯。
解決方案:1. 對高併發操作加鎖, 並且在插入資料時做驗證。2. 可在資料庫層面做出限制,如聯合主鍵和唯一索引均可。
接下來,以這幾個表為例,分析使用兩者之間的區別。
上述提到,可以對 student_id和 course_id做聯合主鍵和唯一索引,均可以實現在資料庫層面對關係表中異常資料做出限制,我們如何選擇呢?
如果是在最初建關係表t_student_course_rel 的時候,就已經考慮到這個需求的話,可以考慮將student_id和course_id直接當做聯合主鍵去使用。建表語句如下圖所示:
create table `t_student_course_rel ` (
`id` bigint(20) not null ,
`student_id` bigint(20) not null ,
`course_id` bigint(20) not null ,
`marks` int(11) not null default 0 ,
primary key (`student_id`, `course_id`)
)
已經建立聯合主鍵的關係表,在面對兩個相同student_id和course_id的資料插入時,會丟擲主鍵重複的異常,如下圖所示
表中已經有了student_id=1和course_id=1的資料,如果再插入便會報錯。
如果當前的表已經執行了很久,不適合再去修改表結構時,或者是表中的主鍵已經確定為其他欄位時,便不再適合使用聯合主鍵,則可以考慮對錶增加非聚集索引之一的唯一索引對關係表做出限制。即將student_id和course_id建立表的唯一索引。其中sql如下:
create table `t_student_course_rel ` (
`id` bigint(20) not null ,
`student_id` bigint(20) not null ,
`course_id` bigint(20) not null ,
`marks` int(11) not null default 0 ,
primary key (`id`),
unique index `in_rel` (`student_id`, `course_id`) using btree
)
(如果表已經建成,則直接用sql加唯一索引即可)
同樣,已經建立聯合唯一索引的關係表,在面對兩個相同student_id和course_id的資料插入時,會丟擲主鍵重複的異常,即可解決。
對關係表中的單個關係的兩個外來鍵id做出聯合主鍵以及聯合唯一索引,可以有效限制關係表中錯誤資料以及異常資料的產生(不管是中期的資料插入,還是後期的資料遷移,都能有效地做出限制),而兩者的選擇就看需求了。
1.聯合主鍵:在建立表的初期就考慮到這個問題,可以對兩個外來鍵id做聯合主鍵,相對於索引來說會省去一些空間。
2.唯一索引:可以在後期加入索引,對兩個外來鍵id做唯一索引,不會修改表結構,但相對來說會增加一些空間。
關係型資料庫 主鍵知識
在關聯式資料庫中,一張表中的每一行資料被稱為一條記錄。一條記錄就是由多個字段組成的。例如,students表的兩行記錄 idclass id name gender score11 小明m902 1小紅f95 每一條記錄都包含若干定義好的字段。同乙個表的所有記錄都有相同的字段定義。對於關係表,有個很...
關係型資料庫和主鍵外來鍵
二 主鍵和外來鍵 定義 表與表之間的聯絡 實現方法 通過設定不同形式的外來鍵來體現表和表的不同關係 既可以把錶a的主鍵充當表b的外來鍵,也可以把錶b的主鍵充當表a的外來鍵 乙個人只有一把鑰匙,一把鑰匙只給乙個人 一對多 把錶a的主鍵充當表b的外來鍵 乙個部門有多個員工,乙個員工只能在乙個部門 在多的...
關係型資料庫和非關係型資料庫
關係型資料庫 mysql oracle等 非關係型資料庫 nosql hbase,mongodb,redis等 優勢 可以在乙個表以及多個表之間做複雜的資料查詢 支援事務,保持資料的一致性。優勢 基於鍵值對,不需要經過sql解析,資料之間沒有耦合,易水平擴充套件。資料儲存在快取中,查詢速度快。可以儲...