來源:互聯網
上載者:User
關鍵字
php
mysql
sql
sqlserver
oracle
本人菜鳥,有個問題困惑了我挺久,今天決定提出來問問大家正確或常用的做法
舉個簡單的例子
文章表: id,標題,內容,……
標籤表: id,標題
以上兩張表顯然都是需要自增ID作為主鍵以確保唯一性的
接下來要設計一個關聯表,把文章和標籤之間關聯起來
文章標籤關聯表: id,文章id,標籤id
可以看出實際上我只需要後面兩個欄位就能夠實現功能了。這是否意味著我完全可以放棄自增的id欄位呢?甚至是可以放棄使用主鍵,單純加索引就行了呢?
如果自增ID主鍵不是必須的,請問我該如何判斷是否需要它?僅僅通過業務需求來判斷嗎?
懇請各位不吝賜教,謝謝
回複內容:
本人菜鳥,有個問題困惑了我挺久,今天決定提出來問問大家正確或常用的做法
舉個簡單的例子
文章表: id,標題,內容,……
標籤表: id,標題
以上兩張表顯然都是需要自增ID作為主鍵以確保唯一性的
接下來要設計一個關聯表,把文章和標籤之間關聯起來
文章標籤關聯表: id,文章id,標籤id
可以看出實際上我只需要後面兩個欄位就能夠實現功能了。這是否意味著我完全可以放棄自增的id欄位呢?甚至是可以放棄使用主鍵,單純加索引就行了呢?
如果自增ID主鍵不是必須的,請問我該如何判斷是否需要它?僅僅通過業務需求來判斷嗎?
懇請各位不吝賜教,謝謝
首先說一下主鍵和索引概念上的不同,主鍵只是個聲明,通過哪些欄位能標識出表的唯一紀錄,只不過是通過唯一索引實現的。
關係型資料庫中絕大部分的表,建議有唯一的主鍵(包括你說的自增ID或UUID方式),屬於邏輯主鍵的範圍,主要是為了程式後續開發方便,尤其是在Web應用上,這個Id可以很方便的在超連結中作為參數傳遞,如:editPost.do?id=123
在你說的文章標籤關聯表的例子中,一般會在文章展示和編輯頁面中,顯示關聯的標籤,就像segmentfault在提問的頁面會顯示所屬的標籤一樣,如果沒有這個id,編輯時刪除一個標籤,假設是通過一個Ajax請求實現的,可以按照這樣的url:deleteTagOfPost.do?id=123,如果沒有的話就會麻煩很多,需要把能夠確定這一行記錄的多個欄位值都放到參數中,如:deleteTagOfPost.do?postId=123&tagId=456,顯然有邏輯主鍵會更方便一些。
另外,用多個欄位的組合作為主鍵來確定唯一的記錄行,屬於物理主鍵的範疇,是和業務的規則強相關的,在開發的方便性、擴充性上不如邏輯主鍵。
首先要明確,主鍵是用來唯一確定一條記錄行的。無論是一個欄位或者多個欄位的組合,嗯,一個表允許設定多主鍵來唯一確定一條記錄。
用自增ID,比如文章,都是單一計數的,一篇文章一個ID標記即可,自增ID可以設定初始值和步進值,一般初始值和步進值預設為1,這些在建表時造成,後續程式員不用單獨為這個欄位再寫代碼,比較簡潔,而且INT值比較省空間。
但是用自增ID不是唯一作為主鍵的方法,比如遇到大量資料時還可以用UNID來作為主鍵,確保沒有重複主鍵記錄。
還有如上說的多個欄位作為主鍵,來確定唯一記錄行,都可以。
用自增ID純粹比較方便而已。
首先糾正錯誤
@Super盒子
沒有自增主鍵是無法修改資料的……
你能確定嗎?
果真如你所說,那請問:
1、 下面這資料有主鍵自增嗎?
2、 這樣的資料是不是不能修改?
主鍵自增主要是方便
主鍵自增主要就是為了方便,讓資料庫中的int自增,保證主鍵唯一性。跟資料能不能修改沒有任何關係,至於怎麼用看個人習慣,跟實際項目需求了。
能不能不這樣做
我的做法是讓程式產生一個主鍵,方法是 時間戳記+隨機數,附上PHP的方法:
這樣子產生的主鍵(小項目是這麼用的)看起來整齊。你用自增的方式:1、2、3、4...10000、3000000000001這樣的主鍵看起來是不是有點怪(我有強迫症),再說了如果把ID為2的刪除了。就成了這樣1、3、4...10000、3000000000001;覺得是不是又不好看了,當然了只有強迫症這麼覺得。
總結:
我覺得只要把握住主鍵唯一性,至於如何產生主鍵,選擇方式很多,int自增、時間戳記+隨機數、表資料中能保證唯一的列都是可以的。這種自增的int似乎被很多人看著不爽(我的老師就覺得不合適),現在想想似乎有些怪異。
純屬個人觀點,歡迎拍磚指正!
經驗之談,如果用有意義的欄位做A表主鍵,業務中涉及更新操作,關聯的表B表的外鍵會失效。如果設定外鍵約束,資料庫會不允許你修改此欄位值。
如果有一個無意義的id做主鍵,邏輯上沒有任何影響,但是開發起來會方便很多
個人人文,id並不是必須的,但是,這是個好的習慣,所以,最好在你每個表都有一個和無意義的ID來標識這條記錄。
另外,ID不一定是自增的,可以有不同的ID建置原則
不一定非要加主鍵
1、不一定必須加主鍵
2、主鍵不一定必須是自增ID
3、很多時候用GUID做為主鍵更合適
我覺得樓主應先分析業務需求,根據需求來定。業務主鍵好+GUID做資料庫的主鍵比較好。
不一定要有自增主鍵。
在mysql中innodb建議每張表要有一個自增主鍵。
自增主鍵會作為表的聚焦索引。
沒有自增主鍵會選擇一個唯一的不為null的索引作為主鍵索引。
沒有這樣的索引,innodb會有一個隱藏的rowid作為聚焦索引,這個索引不能夠引用。(oracle中可以)。
sql查詢時, 索引的大小對查詢速度會有略微的影響。
這個肯定不是了。
定義主鍵的目的是為了查詢出當前表中唯一行
的資料,以便於後期的更新或刪除操作
常見定義主鍵的方式就是自增長;但並非必須要定義自增長來設定為主鍵;
首先得理解主鍵的含義了:一個表必須定義主鍵,且主鍵只能有一個;
一個主鍵不等於
一個欄位這點也必須理解
一個主鍵可以由多個欄位共同組成一個主鍵。但必須組合後,在當前表裡需唯一
例子說明:
單一主鍵(單欄位): 比如使用者表:一般定義那就是uid
作為主鍵。
聯合主鍵(多欄位):
如使用者表、部門表、使用者部門關聯表
使用者表:主鍵uid
;
部門表:主鍵department_id
;
使用者部門關聯表:uid
、department_id
聯合主鍵(一個人不可能在同一部門有兩個名號吧)
沒有自增主鍵是無法修改資料的……
最直觀的影響就是,如果你用有用的欄位做主鍵那麼這個欄位不能為null,且該欄位內容不可修改。