在資料庫設計中,無論如何也該設計一個自增ID欄位作為主鍵嗎?

來源:互聯網
上載者: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
使用者部門關聯表:uiddepartment_id 聯合主鍵(一個人不可能在同一部門有兩個名號吧)

沒有自增主鍵是無法修改資料的……

最直觀的影響就是,如果你用有用的欄位做主鍵那麼這個欄位不能為null,且該欄位內容不可修改。

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.