Tại sao việc đặt tên cột Chính của bảng Bảng Id Id lại bị coi là thông lệ xấu? [đóng cửa]


210

Giáo viên t-sql của tôi nói với chúng tôi rằng việc đặt tên cột "Id" của chúng tôi được coi là thực hành xấu mà không có bất kỳ giải thích nào thêm.

Tại sao việc đặt tên cột PK "Id" được coi là thông lệ xấu?


27
Chà, thực ra nó không phải là một mô tả và Id có nghĩa là "danh tính" rất tự giải thích. Đó là ý kiến ​​của tôi.
Jean-Philippe Leclerc

49
Tôi chắc chắn có rất nhiều cửa hàng sử dụng Id làm tên PK. Cá nhân tôi sử dụng TableId như quy ước đặt tên của mình nhưng tôi sẽ không nói cho ai biết MỘT CÁCH THẬT. Có vẻ như giáo viên của bạn chỉ đang cố gắng trình bày ý kiến ​​của mình như là thực tiễn tốt nhất được chấp nhận rộng rãi.

22
Chắc chắn là loại thực hành xấu không phải là xấu. Vấn đề là để có được sự nhất quán. Nếu bạn sử dụng id, hãy sử dụng nó ở mọi nơi hoặc không sử dụng nó.
deadalnix

57
Bạn có một bảng ... nó được gọi là People, nó có một cột, được gọi là Id, bạn nghĩ Id là gì? Xe hơi? Một chiếc thuyền? ... không, đó là Id người dân, chính là nó. Tôi không nghĩ rằng đó không phải là một thực tiễn xấu và không cần thiết phải đặt tên cho cột PK ngoài Id.
jim

38
Vì vậy, giáo viên đứng trước lớp và nói với bạn đây là một thực hành tồi mà không có một lý do duy nhất? Đó là một thực tế tồi tệ hơn cho một giáo viên.
JeffO

Câu trả lời:


247

Tôi sẽ đi ra và nói rằng: Nó không thực sự là một thực hành tồi (và ngay cả khi nó là, nó không phải xấu).

Bạn có thể đưa ra đối số (như Chad đã chỉ ra) rằng nó có thể che dấu các lỗi như trong truy vấn sau:

SELECT * 
    FROM cars car
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

nhưng điều này có thể dễ dàng được giảm thiểu bằng cách không sử dụng các bí danh nhỏ cho tên bảng của bạn:

SELECT * 
    FROM cars
    JOIN manufacturer
        ON manufacturer.Id = cars.ManufacturerId
    JOIN models
        ON models.Id = cars.ModelId
    JOIN colors
        ON manufacturer.Id = cars.ColorId

Việc thực hành LUÔN LUÔN sử dụng 3 chữ viết tắt đối với tôi có vẻ tồi tệ hơn nhiều so với sử dụng tên cột id. (Trường hợp cụ thể: ai thực sự sẽ viết tắt tên bảng carsbằng chữ viết tắt car? Cái kết thúc đó phục vụ cho cái gì?)

Quan điểm là: nhất quán. Nếu công ty của bạn sử dụng Id và bạn thường mắc lỗi ở trên, thì hãy tập thói quen sử dụng tên bảng đầy đủ. Nếu công ty của bạn cấm cột Id, hãy sải bước và sử dụng bất kỳ quy ước đặt tên nào họ thích.

Tập trung vào việc học những thứ THỰC SỰ THỰC SỰ (chẳng hạn như nhiều truy vấn phụ tương quan lồng nhau) thay vì nghiên cứu các vấn đề như thế này. Vấn đề đặt tên cột của bạn là "ID" gần như là một vấn đề của hương vị hơn là một thực tiễn xấu.


LƯU Ý CHO NGƯỜI CHỈNH SỬA: Lỗi trong truy vấn này là cố ý và đang được sử dụng để tạo điểm. Xin vui lòng đọc câu trả lời đầy đủ trước khi chỉnh sửa.


1
@Chad, nó liên quan đến thực tế là trong truy vấn cụ thể đó, bạn đã sử dụng 3 chữ cái cho bí danh cho tên bảng, ngay cả khi nó không có ý nghĩa ( cars-> car. Cảm ơn Chúa - bạn đã lưu ngón tay của tôi). Đừng đọc quá sâu vào nó.
riwalk

3
tệ hơn tên bí danh của tôi, là sự pha trộn của số nhiều carsmanufacturer. Một là số nhiều, cái còn lại thì không. Nếu mọi người muốn chọn tại db, đó là cách thực hành tồi nên được chọn.
CaffGeek

3
Tôi nghĩ rằng đó là thực hành xấu. Rõ ràng, theo như cách thực hành tồi tệ thì nó không khủng khiếp .. nhưng thật dễ để tránh, tại sao không làm như vậy? Bây giờ, tôi đồng ý, đối với một lớp giới thiệu, đây có phải là điều cần tập trung vào? Có lẽ là không ....
user606723

2
@ user606723, thực sự, tôi nghĩ đối với một lớp giới thiệu, đó là một điều quan trọng để đưa ra quan điểm. Dạy thực hành tốt nhất nên là cơ bản. Mãi cho đến khi bạn có kinh nghiệm, bạn mới hiểu được hậu quả, và sự đánh đổi và khi nào bạn nên đi chệch khỏi những thực tiễn tốt nhất.
CaffGeek

5
@Chad, Đồng ý không đồng ý. Cố gắng dạy cho sinh viên "thực hành tốt nhất" mà không cho phép họ hiểu tại sao đó là những thực tiễn tốt nhất là một nỗ lực vô ích. Và vì bạn không thể bao quát mọi thứ, nên nhấn mạnh vào điểm này bằng "bạn không nên làm điều đó, bạn sẽ hiểu tại sao sau này" là lựa chọn tuyệt vời theo quan điểm của giáo sư. Sinh viên tò mò có thể đăng lên đây hoặc hy vọng tìm thấy câu hỏi này đã được trả lời. (Hoặc hỏi sau giờ học)
user606723

123

Bởi vì khi bạn có một bảng có khóa ngoại, bạn không thể đặt tên khóa đó là "Id". Bạn có tên bảng là TableId

Và sau đó tham gia của bạn trông giống như

SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId

Và lý tưởng, điều kiện của bạn nên có cùng tên trường ở mỗi bên

SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId

Vì vậy, mặc dù việc đặt tên Id là Nhà sản xuất có vẻ không cần thiết, nhưng điều đó khiến bạn ít có lỗi trong các điều kiện tham gia của mình vì các lỗi trở nên rõ ràng.

Điều này có vẻ đơn giản, nhưng khi bạn tham gia một vài bảng, nhiều khả năng bạn sẽ mắc lỗi, hãy tìm bảng bên dưới ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.Id = car.ManufacturerId
    JOIN models mod
        ON mod.Id = car.ModelId
    JOIN colors col
        ON mfg.Id = car.ColorId

Trong khi với cách đặt tên thích hợp, lỗi sẽ xuất hiện ...

SELECT * 
    FROM cars car 
    JOIN manufacturer mfg
        ON mfg.ManufacturerId = car.ManufacturerId
    JOIN models mod
        ON mod.ModelId = car.ModelId
    JOIN colors col
        ON mfg.ManufacturerId = car.ColorId

Một lý do khác để đặt tên cho Id là "xấu" là khi bạn truy vấn thông tin từ một số bảng, bạn sẽ cần đổi tên các cột Id để bạn có thể phân biệt chúng.

SELECT   manufacturer.Id as 'ManufacturerId'
        ,cars.Id as 'CarId'
        --etc
    FROM cars 
    JOIN manufacturer
        ON manufacturer.Id = cars.Id

Với tên chính xác, đây không phải là một vấn đề


174
Không chắc đây là một lời giải thích đủ tốt cho tôi. Không có gì sai khi nói SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId. Tôi đã sử dụng idtrong nhiều năm và không bao giờ tìm thấy những gì bạn mô tả là một vấn đề thực sự.
riwalk

61
Tôi muốn nói rằng thực tế xấu ở đây là các bảng bí danh có tên như mfg hoặc mod. nhà sản xuất.id = Cars.man producker_id rất dễ đọc và lỗi cũng sẽ xảy ra.
deadalnix

5
@Chad> Tôi đã gặp vấn đề với tên biến câm. Nhiều lần. Đối với người nhận, đây là những gì tôi muốn nói với một nhà phát triển trong nhóm của tôi «mfg không có nghĩa là nhà sản xuất, điều đó có nghĩa là bạn lười biếng gõ nhà sản xuất».
deadalnix

9
@ Stargazer712: Thực hiện CHỌN * từ 2 bảng cho 2 cột ID x. ID bây giờ không rõ ràng: bạn tham chiếu theo thứ tự hoặc tên? CHỌN * cũng không phải là thực hành tốt. Lý lẽ kém. Mã dễ vỡ. Chad là chính xác: về cơ bản mã hóa phòng thủ
gbn

6
@gbn, một lần nữa, tất cả sự mơ hồ sẽ biến mất nếu bạn chỉ đơn giản làm SELECT manufacturer.id FROM .... Mọi khó khăn do idcó thể được khắc phục rất dễ dàng, làm cho nó đơn giản chỉ là vấn đề của hương vị.
riwalk

67

Thư viện ActiveRecord của Ruby và GORM của Groovi sử dụng "id" cho khóa thay thế theo mặc định. Tôi thích thực hành này. Sao chép tên bảng trong mỗi tên cột là dư thừa, tẻ nhạt để viết và tẻ nhạt hơn để đọc.


30
+1 cho "và tẻ nhạt hơn để đọc." - các quy ước đặt tên không nên được coi là hỗ trợ ban nhạc cho mã cẩu thả, chúng nên được cải thiện khả năng đọc như một mối quan tâm chính.
ocodo

12
ID tẻ nhạt hơn rất nhiều để đọc
HLGEM

5
@HLGEM: Người ta luôn có thể đủ điều kiện tên cột với tên bảng.
kevin cline

2
Tôi sẽ đồng ý ngoại trừ việc đọc tẻ nhạt hơn. Tôi thực sự thích đọc các tên cột mô tả hơn và dành ít thời gian hơn để tìm ra cột đó thực sự là để làm gì.
Devin Dixon

2
+1, Ghét nhìn thấy các bảng có các cột như Post.postID, Post.postName trong đó chỉ cần sử dụng post.id và post.name thì đẹp hơn nhiều.
Doug

40

Các tên cột phổ biến hoặc chính như "Tên" hoặc "Id" phải được thêm tiền tố với Tên bảng.

Nó loại bỏ sự mơ hồ, dễ dàng tìm kiếm hơn, có nghĩa là bí danh cột ít hơn nhiều khi cần cả hai giá trị "Id".

Một cột ít được sử dụng hoặc kiểm toán hoặc không khóa (giả sử LastUpdatedDateTime) không thành vấn đề


57
Nếu bạn làm điều này, tôi ghét bạn vì đã khiến tôi phải gõ thêm !!!! Tên của bảng là Person, bạn nghĩ Id sẽ là gì? Xe hơi? không, đó là người.
jim

16
@jim, tôi không biết về bạn, nhưng gõ thêm 6 ký tự sẽ khiến tôi mất khoảng nửa giây. Và xem xét tôi hiếm khi chọn từ một bảng, và do đó sẽ kết thúc bằng hai cột có tên 'Id' và dù sao cũng sẽ cần bao gồm tên bảng / bí danh, không có khoản tiết kiệm nào về số lượng ký tự được nhập.
CaffGeek

21
@Chad tôi thấy nó thừa. nếu tôi đang tham gia, c.id = m.man produckerid, với tôi là được. Các cột này thường được "ánh xạ" đến một lớp bằng cách nào đó và để có một lớp với Person.PersonId khiến tôi muốn nôn ... Vâng, tôi hoàn toàn biết rằng tôi có vấn đề.
jim

20
Tôi cũng không đồng ý với điều này. Tại sao dừng lại ở nameid? Tại sao không có mỗi cột có tiền tố với tên bảng của nó? Có vẻ như tùy ý chọn hai tên đó để bắt buộc một tiền tố. Về mặt khái niệm, bạn phải có bảng để có ngữ cảnh của một cột. Tại sao không chỉ sử dụng tên bảng đó để làm rõ truy vấn: Person.Name, Animal.Name, Part.Name, ...
Thomas

11
@Bill Leeper, DRY không phải lúc nào cũng thích hợp trong việc phát triển cơ sở dữ liệu. Trong cơ sở dữ liệu, điều quan trọng là hiệu năng và làm cho cơ sở dữ liệu thực hiện thêm các nguyên tắc DRY đầy đủ (chẳng hạn như sử dụng các hàm vô hướng hoặc các khung nhìn gọi các khung nhìn hoặc truy vấn trả về quá nhiều cột hoặc sử dụng một con trỏ để thêm 1000000 bản ghi để sử dụng một Proc hiện có) thường chống chỉ định Đừng nghĩ rằng chỉ vì một cái gì đó tốt trong thế giới hướng đối tượng mà nó phù hợp trong thiết kế cơ sở dữ liệu. Downvote của bạn là không phù hợp. Sử dụng ID là một antipotype SQL đã biết.
HLGEM

31

Chủ đề này đã chết, nhưng tôi muốn thêm rằng IMO không sử dụng Idlà một thực tiễn xấu. Các Idcột là đặc biệt; đó là các khóa chính. Bất kỳ bảng nào cũng có thể có bất kỳ số lượng khóa ngoại, nhưng nó chỉ có thể có một khóa là chính. Trong cơ sở dữ liệu nơi tất cả các khóa chính được gọi Id, ngay khi bạn nhìn vào bảng, bạn biết chính xác cột nào là khóa chính.

Hãy tin tôi, trong nhiều tháng nay tôi đã dành cả ngày mỗi ngày để làm việc trong rất nhiều cơ sở dữ liệu lớn (Salesforce) và điều tốt nhất tôi có thể nói về các lược đồ là mỗi bảng có một khóa chính được gọi Id. Tôi có thể đảm bảo với bạn rằng tôi hoàn toàn không bao giờ bị nhầm lẫn về việc tham gia khóa chính với khóa ngoại vì PK được gọi Id. Một điều khác mà mọi người không đề cập đến là các bảng có thể có những cái tên dài ngớ ngẩn như Table_ThatDoesGood_stuff__c; Cái tên đó đủ tệ bởi vì kiến ​​trúc sư đã nôn nao vào buổi sáng khi anh ta nghĩ đến cái bàn đó, nhưng bây giờ bạn đang nói với tôi rằng đó là cách thực hành không gọi khóa chính Table_ThatDoesGood_stuff__cId (nhớ rằng tên cột SQL không phân biệt chữ hoa chữ thường).

Thành thật mà nói, vấn đề với hầu hết những người dạy lập trình máy tính là họ đã không viết một dòng mã sản xuất trong nhiều năm, và họ không biết một kỹ sư phần mềm làm việc thực sự làm gì. Đợi cho đến khi bạn bắt đầu làm việc và sau đó tự quyết định những gì bạn nghĩ có phải là một ý tưởng tốt hay không.


2
Đó chỉ là trường hợp nếu không có khóa chính nào của bạn là khóa tổng hợp, điều không may là quá thường xuyên xảy ra. Một người thực sự chỉ nên sử dụng khóa thay thế trong trường hợp cụ thể.
nicodemus13

6
Sử dụng Id như thế bạn sẽ kết thúc với một tình huống mà không cần suy nghĩ các nhà phát triển thêm id khóa chính vào mỗi bảng họ tạo. Một trong những nền tảng của cơ sở dữ liệu quan hệ là việc sử dụng các khóa chính có ý nghĩa và tổng hợp và sử dụng id không giúp ích gì.
Pieter B

Câu trả lời này có vẻ giống như bạn đang nói "Tôi thích Id" với các lập luận có ý kiến. Đối số của bạn là bạn có thể thấy ngay khóa nào là khóa chính bằng cách tìm một khóa có tên là Id. Vâng, nó giống hệt với bảngId . Tôi có thể đảm bảo với bạn Tôi không bao giờ nhầm lẫn khóa nào là khóa chính. Tôi chỉ tìm cái có tên bảng trước id. Không chỉ vậy, nhưng loại bảng bá đạo nào bạn đang làm việc với cột đầu tiên không phải là khóa chính? Tôi cảm thấy như tất cả các lập luận của bạn trong câu trả lời này hoàn toàn dựa trên ưu tiên và gần giống với "bảngId cảm thấy sai đối với tôi".
dallin

@dallin tất cả các câu trả lời đều có ý kiến, nếu không thì ai đó sẽ chỉ liên kết đến tiêu chuẩn chính thức, và không có câu trả lời nào cả!
James

@James Tôi cảm thấy như mục tiêu của các trang web StackExchange là giảm các câu trả lời có ý kiến. Đó là lý do tại sao các câu hỏi được đóng lại vì quá quan tâm. Được cho phép, tôi nghĩ đó là lý do tại sao câu hỏi này bị đóng - bởi vì nó gợi ra những câu trả lời có ý kiến, nhưng tôi cảm thấy câu trả lời cụ thể này bị phản đối quá mức mà không có bất kỳ sự kiện hoặc lập luận hỗ trợ thực sự nào dựa trên sự thật. Toàn bộ câu trả lời có thể được tóm tắt bằng cách nói, "Trong ý kiến ​​của tôi, bạn nên sử dụng Id, chỉ vì đó là những gì tôi thích ". Đó không phải là một câu trả lời có giá trị.
dallin

24

Tôi không coi đó là thực hành xấu. Kiên định là vua, như thường lệ.

Tôi nghĩ đó là tất cả về bối cảnh. Trong ngữ cảnh của bảng, "id" chỉ có nghĩa chính xác là những gì bạn mong đợi, một nhãn giúp xác định duy nhất nó với các bảng khác có thể giống (hoặc xuất hiện) giống hệt nhau.

Trong ngữ cảnh của các phép nối, bạn có trách nhiệm xây dựng các phép nối theo cách sao cho nó có thể đọc được cho bạn và nhóm của bạn. Cũng giống như có thể làm cho mọi thứ trở nên khó khăn với việc đặt cụm từ hoặc đặt tên kém, cũng có thể xây dựng một truy vấn có ý nghĩa với việc sử dụng hiệu quả các bí danh và thậm chí cả các bình luận.

Theo cùng một cách, một lớp Java có tên 'Foo' không có các thuộc tính của nó có tiền tố là 'Foo', không cảm thấy bắt buộc phải đặt tiền tố ID bảng của bạn bằng tên bảng. Nó thường rõ ràng trong bối cảnh ID được đề cập đến là gì.


5
Các bảng cơ sở dữ liệu quan hệ không phải là các lớp .
Adam Robinson

1
Tuy nhiên, chúng là các cấu trúc dữ liệu và chúng tương tự như các lớp PODO. Các vấn đề đặt tên tương tự được áp dụng.
ocodo

4
@Slomojo: Không, chúng không giống với các đối tượng đơn giản. Thiết kế hướng đối tượng và thiết kế cơ sở dữ liệu không giống nhau, và thậm chí không liên quan. Mặc dù trong một số trường hợp, chúng có thể mang lại thiết kế tương tự (hoặc thậm chí giống nhau), điều đó không chỉ ra rằng chúng có liên quan. Ví dụ, các mối quan hệ m: m là tầm thường trong các lớp, nhưng không thể có giữa hai bảng mà không có bảng kết hợp thứ ba.
Adam Robinson

1
Tôi không biết điều này liên quan đến chiến lược đặt tên như thế nào. Sự tương tự của tôi là (rõ ràng?) Chỉ trong phạm vi đó.
ocodo

2
Tôi xin lỗi ý nghĩa ngụ ý của tôi không rõ ràng lắm, tôi nên nói " theo nghĩa này chúng tương tự như các lớp học". Dù bằng cách nào, tôi không nghĩ rằng quá khoa trương về điều này là đặc biệt mang tính xây dựng. Về mặt đặt tên, các bảng và các lớp có chung một số lượng tương tự đáng kể. Các thực tiễn tốt nhất phát triển trong một cống hiến là trò chơi công bằng để sửa đổi, hoặc ít nhất là mở để thảo luận. Có rất nhiều điều trong Hỏi & Đáp này minh họa điều này một cách hiệu quả, tôi không có thêm điều gì cần lưu ý.
ocodo

24

Từ dữ liệu.stackexchange.com

Id trong bài viết

BÙM, câu hỏi đã được trả lời.
Bây giờ hãy nói với giáo viên của bạn rằng SO thực hành thiết kế cơ sở dữ liệu xấu.


8
Tôi đoán tại FK, dựa trên các tên : PostTypeId -> PostTypes.Id; AcceptedAnswerId -> Answers.Id; OwnerUserId -> Users.Id. Tại sao một thực hành dễ dàng bị coi là 'xấu'?
Sjoerd

3
Làm thế nào chính xác điều này chứng minh bất cứ điều gì về thực hành tốt nhất?
GBa

5
Cho dù một cái gì đó được sử dụng tại stack hay không không chứng minh rằng đó là thực hành tốt hay xấu.
Pieter B

2
Những gì nó chứng minh là thực tế này không có cách nào ngăn cấm khả năng mở rộng và hữu ích của một ứng dụng.
Cypher

1
Trên thực tế SO thực hành không hoàn hảo. Tôi sẽ sử dụng cách đặt tên này: PostType -> PostType.Id; Được chấp nhận Trả lời -> Trả lời.Id; Chủ sở hữu Người dùng -> Người dùng.Id
alpav

17

Điều này khiến cho việc thực hiện một phép nối tự nhiên trên bàn trở nên khó khăn (và khó hiểu), thật tệ nếu không nói là rất tệ.

Natural Join là một tạo tác cổ xưa của SQL Lore (nghĩa là đại số quan hệ) mà bạn có thể đã thấy một trong những điều sau: trong một cuốn sách cơ sở dữ liệu có lẽ. Ý tôi là Natrual Join không phải là một ý tưởng SQL mới mẻ, mặc dù dường như phải mất mãi mãi để DBMS thực hiện nó, do đó, nó không phải là một ý tưởng mới để bạn thực hiện nó, thậm chí bạn có thể bỏ qua nó sự tồn tại của nó ngày nay.

Chà, nếu bạn đặt tên cho tất cả ID của khóa chính, thì bạn sẽ mất đi sự dễ dàng và đơn giản của phép nối tự nhiên. select * from dudes natural join carssẽ cần phải được viết select * from dudes inner join cars where cars.dudeid = dudes.idhoặc select * from dudes inner join cars where dudes.carid = cars.id. Nếu bạn có thể tham gia một cách tự nhiên, bạn có thể bỏ qua mối quan hệ thực sự là gì, mà theo tôi, là khá tuyệt vời.


Trừ khi bạn đang viết một thủ tục được lưu trữ, lần cuối cùng là nhà phát triển ứng dụng, bạn thực sự đã viết một bộ chọn SQL được định dạng đầy đủ? Tất cả các ngôn ngữ hiện đại bao gồm một số loại tính năng ORM quản lý mối quan hệ này cho bạn. Tên cột quan trọng hơn nhiều so với việc có thể viết SQL thủ công sạch.
Bill Leeper

4
@Bill Tôi làm tất cả thời gian, nhiều, nhiều lần một ngày, phụ thuộc nhiều vào cơ sở mã của bạn hơn ngôn ngữ bạn đang phát triển. Và, để chẩn đoán, nếu bạn muốn thực hiện một số mối quan hệ tốt và sâu sắc, bạn có thể kết hợp các liên kết tự nhiên đó lại với nhau và hoàn toàn tránh tra cứu ID trường. Và, như thánh Jerome nổi tiếng đã nói, "Sự thiếu hiểu biết về SQL là sự thiếu hiểu biết về cơ sở dữ liệu".
Peter Turner

Bên cạnh thực tế là các phép nối tự nhiên không được hỗ trợ phổ biến, IMO, các phép nối tự nhiên khó đọc hơn. Có hai cột trong mối quan hệ hoặc chỉ một? Tốt hơn nhiều để được rõ ràng và tránh tham gia tự nhiên.
Thomas

1
@Thomas, tôi cũng sẽ không đặt các phép nối tự nhiên vào mã, nhưng để chẩn đoán, tôi thấy chúng khá hữu ích khi cơ sở dữ liệu được mô hình hóa để chúng thực sự hoạt động.
Peter Turner

16

Có một tình huống mà việc dán "ID" trên mỗi bảng không phải là ý tưởng tốt nhất: USINGtừ khóa, nếu nó được hỗ trợ. Chúng tôi sử dụng nó thường xuyên trong MySQL.

Ví dụ: nếu bạn có fooTablecột fooTableIdbarTablekhóa ngoại fooTableId, thì các truy vấn của bạn có thể được xây dựng như sau:

SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)

Nó không chỉ tiết kiệm gõ, mà còn dễ đọc hơn nhiều so với cách thay thế:

SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)

Đây là câu trả lời phù hợp nhất với tôi. Các USINGtừ khóa được hỗ trợ bởi cơ sở dữ liệu Postgres / mysql / sqlite, có nghĩa là ít gõ mà một số các danh sách câu trả lời khác như một lý do để sử dụng id, và cuối cùng là theo ý kiến chủ quan của tôi là dễ đọc hơn.
Michael Barton

11

Tại sao không chỉ hỏi giáo viên của bạn?

Hãy nghĩ về điều này, khi tất cả các cột PK trong bảng của bạn được đặt tên, IDđiều đó làm cho việc sử dụng chúng làm khóa ngoại là một cơn ác mộng.

Tên cột cần có ý nghĩa về mặt ngữ nghĩa. IDlà chung chung.


8
quá chung chung để làm gì? id của một bảng?
jim

3
@Jim của bảng nào? idmột mình không có nghĩa gì cả, đặc biệt là trong bối cảnh khóa ngoại sang bảng khác. Điều này không có gì để làm classesvà tất cả mọi thứ để làm với thiết kế cơ sở dữ liệu quan hệ cơ bản cơ bản tốt.

10
Để được hơi mệt mỏi, bảng mà nó thuộc về. table.idlà một cách hoàn toàn chấp nhận được khi đề cập đến một idlĩnh vực. Tiền tố tên trường với tên bảng là dư thừa.
ocodo

2
@Slomoj nó không gõ nhiều hơn bao gồm tên trong cột và bùng nổ hơn khi đặt tên bảng cho các chữ viết tắt một hoặc hai chữ cái trong các phép nối quái vật.

6
Bạn đang đề cập đến cơn ác mộng nào? Giả sử bạn có một cấu trúc nhân viên tự giới thiệu với một cột đại diện cho người quản lý của họ. Bạn gọi khóa ngoại là gì? Bạn không thể gọi nó là EmployeeId vì đó có lẽ là PK của bạn. Tên của FK không phải khớp với PK. Nó nên được đặt tên cho những gì nó đại diện cho thực thể mà nó được chứa.
Thomas

7

ID xấu vì những lý do sau:

Nếu bạn thực hiện nhiều truy vấn báo cáo, bạn luôn phải đặt bí danh cho các cột nếu bạn muốn xem cả hai. Vì vậy, nó trở nên lãng phí thời gian khi bạn có thể đặt tên đúng cho nó để bắt đầu. Các truy vấn phức tạp này đủ khó (tôi viết các truy vấn có thể dài hàng trăm dòng) mà không phải chịu thêm gánh nặng khi thực hiện các công việc không cần thiết.

Nó có thể gây ra lỗi mã. Nếu bạn sử dụng cơ sở dữ liệu cho phép sử dụng phép nối tự nhiên (không phải tôi nghĩ bạn nên sử dụng cơ sở dữ liệu đó nhưng khi có tính năng thì sẽ có người sử dụng chúng), bạn sẽ tham gia sai nếu bạn nhận được một nhà phát triển sử dụng nó.

Nếu bạn đang sao chép các phép nối để tạo một truy vấn phức tạp, thật dễ dàng quên thay đổi bí danh thành một truy vấn bạn muốn và nhận được một phép nối không chính xác. Nếu mỗi id được đặt tên theo bảng, thì bạn sẽ thường gặp lỗi cú pháp. Cũng dễ dàng hơn để phát hiện nếu truy vấn phức tạp tham gia không chính xác nếu tên pPK và tên FK khớp.


+1: Đây là những lý do thuyết phục theo ý kiến ​​của tôi, trong khi những câu trả lời khác phản đối IDkhông thuyết phục tôi chút nào.
phoog

Re: "Nếu bạn đang sao chép các phép nối để tạo một truy vấn phức tạp" - vì vậy vấn đề của bạn là sao chép và dán. Dừng sao chép và dán và bạn sẽ thấy cách đặt tên car.id tiện lợi như thế nào. Để tham gia FK, hãy sử dụng car.mfg = mfg.id, car.color = color.id, car.model = model.id - rất đơn giản và phù hợp với những gì bạn sẽ viết trong LINQ.
alpav

Hãy thử viết một cái gì đó với 30 tham gia và bạn sẽ thấy lý do tại sao nó là một antipotype.
HLGEM

Bí danh là lý do đầu tiên và quan trọng nhất - thật đau đầu khi làm các báo cáo phức tạp lớn. Tham gia tự nhiên chỉ là một phần thưởng ngọt ngào. Thật đáng ngạc nhiên khi các câu trả lời khác chỉ bỏ qua điểm này. Tôi nghĩ rằng thêm một số ví dụ sẽ làm cho điểm rõ ràng hơn và đưa câu trả lời này cao hơn đến nơi cần có.
Lulu

5

Có một số câu trả lời tiếp cận những gì tôi sẽ xem là lý do quan trọng nhất cho việc không sử dụng "id" làm tên cột cho khóa chính trong bảng: cụ thể là tính nhất quán và giảm sự mơ hồ.

Tuy nhiên, đối với tôi, lợi ích chính được nhận ra bởi lập trình viên bảo trì, đặc biệt là người không liên quan đến sự phát triển ban đầu. Nếu bạn đã sử dụng tên "PersonID" cho ID trong bảng Person và thường xuyên sử dụng tên đó làm khóa ngoại, việc viết một truy vấn đối với lược đồ để tìm ra bảng nào có PersonID mà không cần phải suy ra "PersonID" là tên được sử dụng khi nó là khóa ngoại. Hãy nhớ rằng, đúng hay sai, các mối quan hệ khóa ngoài không phải lúc nào cũng được thực thi trong tất cả các dự án.

Có một trường hợp cạnh trong đó một bảng có thể cần có hai khóa ngoại cho cùng một bảng, nhưng trong những trường hợp đó tôi sẽ đặt tên khóa gốc làm tên hậu tố cho cột, do đó, có thể dễ dàng tìm thấy ký tự đại diện,% PersonID những trường hợp đó là tốt.

Có, phần lớn điều này có thể được thực hiện bằng một tiêu chuẩn là có "id" và biết luôn luôn sử dụng nó như là "tên bảng", nhưng điều đó đòi hỏi cả hai phải biết rằng thực tiễn được áp dụng và phụ thuộc vào các nhà phát triển ban đầu để theo dõi với ít hơn thực hành tiêu chuẩn trực quan.

Trong khi một số người đã chỉ ra rằng nó đòi hỏi một số nét chính để viết ra các tên cột dài hơn, tôi sẽ khẳng định rằng việc viết mã chỉ là một phần nhỏ trong vòng đời hoạt động của chương trình. Nếu lưu tổ hợp phím nhà phát triển là mục tiêu, không bao giờ nên viết bình luận.

Là một người đã dành nhiều năm để duy trì các dự án lớn với hàng trăm bảng, tôi rất thích các tên nhất quán cho một khóa trên các bảng.


Giả sử một Companiesbảng có 2 khóa ngoại vào một Personsbảng. Một đại diện cho Chủ tịch của công ty; người kia đại diện cho Thủ quỹ của công ty. Bạn thực sự sẽ gọi các cột PersonID1PersonID2? Nó sẽ được mô tả nhiều hơn để gọi cho họ PresidentIDTreasurerID. Tôi thấy nó dễ đọc inner join Person AS Presidents ON Company.PresidentID = Presidents.IDhơn nhiềuinner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
phoog

1
Không. Trong ví dụ của bạn, tôi có thể có một CompanyOfficerhoặc CompanyPersonbảng cho phép mối quan hệ nhiều-nhiều với giữa CompanyPersonvới thông tin bổ sung về bản chất của mối quan hệ. Nếu tôi triển khai nó trong Companybảng, tôi sẽ sử dụng tên cột PresidentPersonIDTreasurerPersonIDđể giữ phần * PersonID của tên trong khi thêm mô tả bổ sung. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
Malachi

5

Việc sử dụng Id làm trường khóa chính dẫn đến thực tiễn nơi id được thêm vào mỗi bảng. Rất nhiều bảng đã có thông tin duy nhất xác định duy nhất một bản ghi. Sử dụng THAT làm khóa chính và không phải là trường id bạn thêm vào mỗi bảng. Đó là một trong những nền tảng của cơ sở dữ liệu quan hệ.

Và đó là lý do tại sao sử dụng id là thông lệ xấu: id thường không phải là thông tin chỉ là tự động tăng.

xem xét các bảng sau:

PK id | Countryid   | Countryname
    1 |         840 | United States
    2 |         528 | the Netherlands

Điều sai với bảng này là nó cho phép người dùng thêm một dòng khác: Hoa Kỳ, với mã quốc gia 840. Nó vừa phá vỡ tính toàn vẹn quan hệ. Tất nhiên, bạn có thể thực thi tính duy nhất trên các cột riêng lẻ hoặc bạn chỉ có thể sử dụng khóa chính đã có sẵn:

PK Countryid   | Countryname
           840 | United States
           528 | the Netherlands

Bằng cách đó, bạn sử dụng thông tin bạn đã có làm khóa chính, là trung tâm của thiết kế cơ sở dữ liệu quan hệ.


1
Bạn sẽ hiểu lý do tại sao mọi người thêm một cột khóa chung vào mỗi bảng khi bạn phải di chuyển cơ sở dữ liệu giữa các hệ thống khác nhau hoặc có niềm vui hợp nhất cơ sở dữ liệu với nhau.
Cypher

1
Điều này đôi khi là trường hợp, nhưng theo kinh nghiệm của tôi, nó khá hiếm khi có một khóa bất biến độc đáo đẹp. Nhưng ngay cả trong ví dụ của bạn, bạn có một số duy nhất vô nghĩa để xác định các quốc gia, chỉ một số được phân bổ bởi ISO không phải bởi cơ sở dữ liệu của bạn.
CodeInChaos

Và bây giờ khi tên quốc gia thay đổi, bạn phải cập nhật nó trong toàn bộ cơ sở dữ liệu của mình để sửa chữa. Nếu bạn chỉ đơn giản sử dụng khóa thay thế (như ... "id"), bản cập nhật sẽ không đáng kể. Chìa khóa tự nhiên rất tuyệt - khi chúng hoàn toàn bất biến, và không bao giờ thay đổi. Thực tế có rất ít trường hợp điều này là đúng.
Gerrat

@Gerrat: Nếu tên quốc gia thay đổi, mã số ISO 3166-1 giữ nguyên, chỉ có mã ISO 3166-1 alpha-2 và alpha-3 thay đổi. Điều này đã xảy ra với Miến Điện / Myanmar chẳng hạn. Tương tự, nếu một quốc gia thay đổi lãnh thổ nhưng vẫn giữ nguyên tên, mã số ISO 3166-1 sẽ thay đổi, nhưng mã ISO 3166-1 alpha-2 và alpha-3 vẫn tồn tại. Điều này xảy ra khi Nam Sudan tách khỏi Sudan và Eritrea tách khỏi Ethiopia. Khi Đông và Tây Đức tái hợp, họ giữ mã alpha-2 và alpha-3 của Tây Đức nhưng có mã số mới. Khi các quốc gia hoàn toàn tan rã hoặc biến đổi (nghĩ rằng
Jörg W Mittag

Kết quả của cuộc chiến Balkan thập niên 90), họ nhận được cả hai mã số và alpha-2 và alpha-3 mới.
Jörg W Mittag

4

Tôi luôn sử dụng 'id' làm tên cột chính cho mỗi bảng đơn giản vì đó là quy ước của các khung tôi sử dụng (Ruby on Rails, CakePHP), vì vậy tôi không phải ghi đè lên nó mọi lúc.

Điều đó sẽ không đánh bại lý do học tập cho tôi.


2

Tôi không nghĩ rằng đó là một thực hành xấu nếu nó được sử dụng đúng cách. Thông thường có trường ID tự động tăng gọi là "ID" mà bạn không bao giờ phải chạm và sử dụng số nhận dạng thân thiện hơn cho ứng dụng. Nó có thể là một chút rườm rà để viết mã như thế from tableA a inner join tableB b on a.id = b.a_idnhưng mã đó có thể được giấu đi.

Là một sở thích cá nhân, tôi có xu hướng tiền tố Id với tên của thực thể, nhưng tôi không thấy vấn đề thực sự khi chỉ sử dụng Idnếu nó được xử lý hoàn toàn bởi cơ sở dữ liệu.


Bạn sẽ không bao giờ tham gia hai bảng theo khóa chính của mỗi người, đặc biệt là id tăng tự động. Mẫu ở trên sẽ là từ bảngA một bảng tham gia bên trongB b trên a.id = b.table_a_id.
Bill Leeper

Vâng, đó là những gì tôi muốn nói. Hầu như giờ ăn trưa và cần năng lượng.
Wayne Molina

2

ID là đủ phổ biến, mà tôi không nghĩ rằng nó sẽ gây nhầm lẫn cho bất cứ ai. Bạn sẽ luôn muốn biết bảng. Đặt tên trường trong mã sản xuất mà không bao gồm bảng / bí danh là một thực tế xấu. Nếu bạn quá lo lắng về việc có thể nhanh chóng nhập các truy vấn đặc biệt, bạn sẽ tự mình thực hiện.

Chỉ hy vọng không ai phát triển cơ sở dữ liệu sql trong đó ID là một từ dành riêng.

CREATE TABLE CAR (ID);

Chăm sóc tên trường, khóa chính và tự động tăng thêm 1 bắt đầu bằng 1 tất cả trong một gói 2 ký tự nhỏ. Ồ, và tôi sẽ gọi nó là CARS nhưng nếu chúng ta sẽ tiết kiệm các nét chính và ai thực sự nghĩ rằng một bảng gọi là CAR sẽ chỉ có một?


1
điều này cho thấy tại sao kiến ​​thức về lý thuyết quan hệ chính thức là quan trọng, tên bảng biểu thị một hàng duy nhất là gì. Bảng Carđại diện cho một Tablenơi mỗi Rowđại diện cho một Car. Kêu gọi Carsthay đổi ngữ nghĩa và cho thấy sự thiếu hiểu biết hoàn toàn về các nguyên tắc cơ bản của lý thuyết quan hệ chính thức. Rails là một ví dụ điển hình của một người biết đủ nguy hiểm .

2

Câu hỏi này đã bị đánh đập nhiều lần, nhưng tôi nghĩ rằng tôi cũng sẽ thêm ý kiến ​​của mình.

  1. Tôi sử dụng id có nghĩa là đó là định danh cho mỗi bảng, vì vậy khi tôi tham gia vào một bảng và tôi cần khóa chính, tôi sẽ tự động tham gia vào khóa chính.

  2. Trường id là tự động, không dấu (có nghĩa là tôi không bao giờ phải đặt giá trị của nó và nó không thể âm)

  3. Đối với khóa ngoại, tôi sử dụng tablenameid (lại là vấn đề về kiểu dáng), nhưng khóa chính tôi tham gia là trường id của bảng, vì vậy tính nhất quán có nghĩa là tôi luôn có thể kiểm tra các truy vấn dễ dàng

  4. id cũng ngắn và ngọt ngào

  5. Quy ước bổ sung - sử dụng chữ thường cho tất cả các tên bảng và cột, do đó không có vấn đề nào được tìm thấy do trường hợp


1

Một điều khác cần xem xét là nếu tên khóa chính khác với tên khóa ngoại, thì không thể sử dụng một số công cụ của bên thứ ba.

Ví dụ: bạn sẽ không thể tải lược đồ của mình vào một công cụ như Visio và để nó tạo ra ERD chính xác.


Đó sẽ là lỗi của công cụ bên thứ ba. Các quy ước đặt tên cột không thay thế cho các khóa ngoại thực tế, mà công cụ nên hướng nội.
Gerrat

1

Tôi thấy mọi người ở đây bao gồm khá nhiều khía cạnh nhưng tôi muốn thêm rằng "id" không phải và không nên được đọc là "định danh" mà nó giống như một "chỉ mục" và chắc chắn nó không nêu hoặc mô tả danh tính của hàng. (Tôi có thể đã sử dụng từ ngữ sai ở đây, vui lòng sửa lại cho tôi nếu tôi đã làm)

Đó là ít nhiều cách mọi người đọc dữ liệu bảng và cách họ viết mã của họ. Cá nhân tôi và rất có thể đây là cách phổ biến nhất mà tôi thấy thường xuyên hơn là các lập trình viên viết toàn bộ tài liệu tham khảo table.id, ngay cả khi họ không cần phải thực hiện liên kết hoặc / và tham gia. Ví dụ:

SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>

Bằng cách đó, bạn có thể dịch nó sang tiếng Anh là "Hãy cho tôi màu sắc và kiểu dáng của chiếc xe được đánh số là". và không phải là "Hãy cho tôi màu sắc và kiểu xe của chiếc xe được xác định là số." ID không đại diện cho chiếc xe theo bất kỳ cách nào, đó chỉ là chỉ số của xe, một số sê-ri nếu bạn muốn. Giống như khi bạn muốn lấy phần tử thứ ba từ một mảng.

Vì vậy, để tóm tắt những gì tôi muốn thêm là đó chỉ là vấn đề ưu tiên và cách đọc mô tả SQL là phổ biến nhất.

Mặc dù, có một số trường hợp không được sử dụng, chẳng hạn như (một ví dụ hiếm gặp hơn nhiều) khi ID là một chuỗi thực sự mô tả. Ví dụ id = "RedFordMustang1970"hoặc một cái gì đó tương tự. Tôi thực sự hy vọng tôi có thể giải thích điều này ít nhất để có được ý tưởng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.