Guru t-sql saya memberi tahu kami bahwa memberi nama kolom PK kami "Id" dianggap praktik buruk tanpa penjelasan lebih lanjut.
Mengapa penamaan tabel PK kolom "Id" dianggap praktik yang buruk?
Guru t-sql saya memberi tahu kami bahwa memberi nama kolom PK kami "Id" dianggap praktik buruk tanpa penjelasan lebih lanjut.
Mengapa penamaan tabel PK kolom "Id" dianggap praktik yang buruk?
Jawaban:
Aku akan keluar dan mengatakan itu: Ini tidak benar-benar praktek yang buruk (dan bahkan jika itu, yang tidak yang buruk).
Anda bisa membuat argumen (seperti yang ditunjukkan Chad ) yang bisa menutupi kesalahan seperti dalam kueri berikut:
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
tetapi ini dapat dengan mudah dikurangi dengan tidak menggunakan alias kecil untuk nama tabel Anda:
SELECT *
FROM cars
JOIN manufacturer
ON manufacturer.Id = cars.ManufacturerId
JOIN models
ON models.Id = cars.ModelId
JOIN colors
ON manufacturer.Id = cars.ColorId
Praktek SELALU menggunakan singkatan 3 huruf tampaknya jauh lebih buruk bagi saya daripada menggunakan nama kolom id
. (Contoh kasus: siapa yang sebenarnya akan menyingkat nama tabel cars
dengan singkatan car
? Apa manfaatnya?)
Intinya adalah: konsisten. Jika perusahaan Anda menggunakan Id dan Anda biasanya membuat kesalahan di atas, maka biasakan menggunakan nama tabel penuh. Jika perusahaan Anda mencekal kolom Id, tenang dan gunakan konvensi penamaan apa pun yang mereka sukai.
Berfokuslah pada mempelajari hal-hal yang benar-benar praktik buruk (seperti beberapa kueri yang berkorelasi bersarang) daripada memikirkan masalah seperti ini. Masalah penamaan kolom Anda "ID" lebih dekat menjadi masalah selera daripada menjadi praktik yang buruk.
A CATATAN UNTUK EDITOR: Kesalahan dalam kueri ini disengaja dan sedang digunakan untuk membuat poin. Harap baca jawaban lengkap sebelum mengedit.
cars
-> car
. Terima kasih Tuhan - Anda telah menyelamatkan jari saya). Jangan membacanya terlalu dalam.
cars
dan manufacturer
. Satu jamak, yang lain tidak. Jika orang ingin memilih di db, itu adalah praktik buruk yang harus diambil.
Karena ketika Anda memiliki tabel dengan kunci asing, Anda tidak dapat menamai kunci asing itu "Id". Anda memiliki nama tabel itu TableId
Dan kemudian bergabung Anda terlihat seperti
SELECT * FROM cars c JOIN manufacturer m ON m.Id = c.ManufacturerId
Dan idealnya, kondisi Anda harus memiliki nama bidang yang sama di setiap sisi
SELECT * FROM cars c JOIN manufacturer m ON m.ManufacturerId = c.ManufacturerId
Jadi, meskipun tampak berlebihan untuk menyebut Id sebagai ManufacturerId, itu membuat Anda tidak memiliki banyak kesalahan dalam kondisi bergabung Anda karena kesalahan menjadi jelas.
Ini tampaknya sederhana, tetapi ketika Anda bergabung dengan beberapa tabel, semakin besar kemungkinan Anda akan membuat kesalahan, temukan yang di bawah ini ...
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
Sedangkan dengan penamaan yang tepat, kesalahan muncul ...
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
Alasan lain menamai mereka Id adalah "buruk" adalah bahwa ketika Anda meminta informasi dari beberapa tabel Anda perlu mengubah nama kolom Id sehingga Anda dapat membedakannya.
SELECT manufacturer.Id as 'ManufacturerId'
,cars.Id as 'CarId'
--etc
FROM cars
JOIN manufacturer
ON manufacturer.Id = cars.Id
Dengan nama yang akurat ini tidak terlalu menjadi masalah
SELECT * FROM cars c JOIN manufacturer m ON manufacturer.Id = c.ManufacturerId
. Saya telah menggunakan id
selama bertahun-tahun dan tidak pernah menemukan apa yang Anda gambarkan sebagai masalah nyata.
SELECT manufacturer.id FROM ...
. Setiap kesulitan yang dihasilkan id
dapat diatasi dengan sangat mudah, menjadikannya hanya masalah selera.
Pustaka ActiveRecord Ruby dan GORM Groovy menggunakan "id" untuk kunci pengganti secara default. Saya suka latihan ini. Duplikasi nama tabel di setiap nama kolom adalah mubazir, membosankan untuk ditulis, dan lebih membosankan untuk dibaca.
Nama kolom umum atau kunci seperti "Nama" atau "Id" harus diawali dengan TableName.
Ini menghilangkan ambiguitas, lebih mudah untuk mencari, berarti alias kolom jauh lebih sedikit ketika kedua nilai "Id" diperlukan.
Kolom atau non-kunci yang digunakan atau audit yang lebih rendah (katakanlah LastUpdatedDateTime) tidak masalah
name
dan id
? Mengapa tidak setiap kolom diawali dengan nama tabelnya? Tampaknya sewenang-wenang untuk memilih kedua nama untuk mengamanatkan awalan. Secara konseptual, Anda harus memiliki tabel untuk tetap memiliki konteks kolom. Mengapa tidak menggunakan nama tabel itu untuk mengklarifikasi kueri: Person.Name, Animal.Name, Part.Name, ...
Utas ini sudah mati, tetapi saya ingin menambahkan bahwa IMO yang tidak digunakan Id
adalah praktik yang buruk. The Id
kolom khusus; itu adalah yang primary key. Setiap tabel dapat memiliki sejumlah kunci asing, tetapi hanya dapat memiliki satu kunci yang utama. Dalam database tempat semua kunci utama dipanggil Id
, segera setelah Anda melihat tabel Anda tahu persis kolom mana yang merupakan kunci utama.
Percayalah, selama berbulan-bulan sekarang saya telah menghabiskan sepanjang hari setiap hari bekerja di banyak database besar (Tenaga Penjualan) dan hal terbaik yang dapat saya katakan tentang skema adalah bahwa setiap tabel memiliki kunci primer yang disebut Id
. Saya dapat meyakinkan Anda bahwa saya sama sekali tidak pernah bingung tentang bergabung dengan kunci utama ke kunci asing karena PK disebut Id
. Hal lain yang belum disebutkan orang adalah bahwa tabel dapat memiliki nama-nama konyol yang panjang seperti Table_ThatDoesGood_stuff__c
; nama itu cukup buruk karena arsitek mengalami mabuk pada pagi hari dia memikirkan tabel itu, tetapi sekarang Anda mengatakan kepada saya bahwa itu adalah praktik yang buruk untuk tidak memanggil kunci utama Table_ThatDoesGood_stuff__cId
(mengingat bahwa nama kolom SQL pada umumnya tidak peka huruf besar-kecil).
Sejujurnya, masalah dengan kebanyakan orang yang mengajar pemrograman komputer adalah bahwa mereka belum pernah menulis sederet kode produksi selama bertahun-tahun, jika pernah, dan mereka tidak tahu apa yang sebenarnya dilakukan oleh insinyur perangkat lunak yang berfungsi. Tunggu sampai Anda mulai bekerja dan kemudian putuskan sendiri apa yang menurut Anda merupakan ide bagus atau tidak.
Saya tidak menganggapnya sebagai praktik buruk. Konsistensi adalah raja, seperti biasa.
Saya pikir ini semua tentang konteks. Dalam konteks tabel sendiri, "id" hanya berarti persis apa yang Anda harapkan, label untuk membantu mengidentifikasi secara unik terhadap orang lain yang mungkin (atau tampak) identik.
Dalam konteks gabungan, Anda bertanggung jawab untuk membuat gabungan sedemikian rupa agar dapat dibaca oleh Anda dan tim Anda. Seperti halnya membuat hal-hal tampak sulit dengan ungkapan atau penamaan yang buruk, juga memungkinkan untuk membuat kueri yang bermakna dengan penggunaan alias yang efektif dan bahkan komentar.
Dengan cara yang sama kelas Java yang disebut 'Foo' tidak memiliki propertinya diawali oleh 'Foo', jangan merasa berkewajiban untuk awalan ID tabel Anda dengan nama tabel. Biasanya jelas dalam konteks apa ID yang dimaksud.
BOOM, pertanyaan dijawab.
Sekarang, beri tahu guru Anda bahwa SO mempraktikkan desain basis data yang buruk.
PostTypeId -> PostTypes.Id
:; AcceptedAnswerId -> Answers.Id
; OwnerUserId -> Users.Id
. Mengapa praktik yang semudah itu dianggap 'buruk'?
Itu membuatnya sulit (dan membingungkan) untuk melakukan join alami di atas meja, oleh karena itu ya, itu buruk jika tidak terlalu buruk.
Natural Join adalah artefak kuno SQL Lore (yaitu aljabar relasional) yang mungkin pernah Anda lihat: ⋈ dalam buku database mungkin. Apa yang saya maksud adalah Natrual Join bukanlah ide SQL baru yang ketinggalan jaman, meskipun sepertinya butuh waktu lama bagi DBMS untuk mengimplementasikannya, oleh karena itu bukan ide ketinggalan jaman baru bagi Anda untuk mengimplementasikannya, bahkan mungkin tidak masuk akal bagi Anda untuk mengabaikannya keberadaannya saat ini.
Nah, jika Anda memberi nama semua ID kunci utama Anda, maka Anda kehilangan kemudahan dan kesederhanaan dari gabungan alami. select * from dudes natural join cars
perlu ditulis select * from dudes inner join cars where cars.dudeid = dudes.id
atau select * from dudes inner join cars where dudes.carid = cars.id
. Jika Anda dapat melakukan join natural, Anda bisa mengabaikan apa sebenarnya relasinya, yang, saya percaya, cukup mengagumkan.
Ada situasi di mana menempelkan "ID" di setiap tabel bukan ide terbaik: USING
kata kunci, jika didukung. Kami sering menggunakannya di MySQL.
Misalnya, jika Anda memiliki fooTable
dengan kolom fooTableId
dan barTable
dengan kunci asing fooTableId
, maka pertanyaan Anda dapat dibuat seperti itu:
SELECT fooTableId, fooField1, barField2 FROM fooTable INNER JOIN barTable USING (fooTableId)
Ini tidak hanya menghemat pengetikan, tetapi jauh lebih mudah dibaca dibandingkan dengan alternatif:
SELECT fooTable.Id, fooField1, barField2 FROM fooTable INNER JOIN barTable ON (fooTable.Id = barTable.foTableId)
USING
kunci ini didukung oleh database postgres / mysql / sqlite, berarti lebih sedikit mengetik di mana beberapa dari daftar jawaban lainnya sebagai alasan untuk menggunakan id
, dan akhirnya menurut pendapat subjektif saya lebih mudah dibaca.
Mengapa tidak bertanya kepada gurumu saja?
Pikirkan tentang ini, ketika semua kolom tabel PK Anda dinamai ID
itu menjadikannya sebagai kunci asing mimpi buruk.
Nama kolom harus signifikan secara semantik. ID
adalah untuk generik.
id
sendiri tidak berarti apa-apa, terutama dalam konteks kunci asing ke tabel lain. Ini tidak ada hubungannya dengan classes
dan semuanya berhubungan dengan desain basis data relasional dasar yang bagus.
table.id
adalah cara yang bisa diterima untuk merujuk ke suatu id
bidang. Awalan nama bidang dengan nama tabel berlebihan.
ID buruk karena alasan berikut:
Jika Anda melakukan banyak permintaan pelaporan, Anda harus selalu alias kolom jika Anda ingin melihat keduanya. Jadi itu menjadi buang-buang waktu ketika Anda bisa menyebutkannya dengan benar. Pertanyaan kompleks ini cukup sulit (saya menulis pertanyaan yang panjangnya ratusan baris) tanpa beban tambahan untuk melakukan pekerjaan yang tidak perlu.
Itu dapat menyebabkan kesalahan kode. Jika Anda menggunakan database yang memungkinkan penggunaan natural join (bukan berarti saya pikir Anda harus menggunakannya, tetapi ketika fitur tersedia, seseorang akan menggunakannya), Anda akan bergabung pada hal yang salah jika Anda mendapatkan pengembang yang menggunakannya.
Jika Anda menyalin gabungan untuk membuat kueri yang kompleks, mudah untuk lupa mengubah alias ke yang Anda inginkan dan mendapatkan salah bergabung. Jika setiap id diberi nama setelah tabel itu berada, maka Anda biasanya akan mendapatkan kesalahan sintaksis. Juga lebih mudah dikenali jika gabungan dalam kueri kompleks salah jika nama pPK dan nama FK cocok.
ID
tidak meyakinkan saya sama sekali.
Ada beberapa jawaban yang mendekati apa yang saya anggap sebagai alasan paling penting untuk tidak menggunakan "id" sebagai nama kolom untuk kunci utama dalam tabel: yaitu konsistensi dan mengurangi ambiguitas.
Namun, bagi saya manfaat utama disadari oleh programmer pemeliharaan, khususnya yang tidak terlibat dengan pengembangan asli. Jika Anda menggunakan nama "PersonID" untuk ID di tabel Person dan secara konsisten menggunakan nama itu sebagai kunci asing, itu sepele untuk menulis kueri terhadap skema untuk mengetahui tabel apa yang memiliki PersonID tanpa harus menyimpulkan bahwa "PersonID" adalah nama yang digunakan saat itu adalah kunci asing. Ingat, benar atau salah, hubungan kunci asing tidak selalu diberlakukan di semua proyek.
Ada kasus tepi di mana satu tabel mungkin perlu memiliki dua kunci asing ke tabel yang sama, tetapi dalam kasus seperti itu saya akan meletakkan nama kunci asli sebagai nama akhiran untuk kolom, sehingga pencocokan wildcard,% PersonID, dapat dengan mudah menemukan contoh-contoh itu juga.
Ya, banyak dari ini dapat dicapai dengan standar memiliki "id" dan mengetahui untuk selalu menggunakannya sebagai "tableNameID", tetapi itu membutuhkan keduanya mengetahui bahwa praktiknya sudah ada dan tergantung pada pengembang asli untuk menindaklanjuti dengan yang kurang praktik standar intuitif.
Sementara beberapa orang telah menunjukkan bahwa memang diperlukan beberapa stroke kunci tambahan untuk menuliskan nama kolom yang lebih panjang, saya berpendapat bahwa menulis kode hanya sebagian kecil dari kehidupan aktif program. Jika menyimpan penekanan tombol pengembang adalah tujuannya, komentar tidak boleh ditulis.
Sebagai seseorang yang telah menghabiskan bertahun-tahun mempertahankan proyek besar dengan ratusan tabel, saya akan lebih suka nama yang konsisten untuk kunci di seluruh tabel.
Companies
tabel memiliki 2 kunci asing ke sebuah Persons
tabel. Satu mewakili Presiden perusahaan; yang lain mewakili Bendahara perusahaan. Apakah Anda benar-benar memanggil kolom PersonID1
dan PersonID2
? Akan jauh lebih deskriptif untuk memanggil mereka PresidentID
dan TreasurerID
. Saya merasa lebih mudah membaca inner join Person AS Presidents ON Company.PresidentID = Presidents.ID
daripadainner join Person AS Person1 ON Company.PersonID1 = Person1.PersonID
CompanyOfficer
atau CompanyPerson
yang memungkinkan hubungan banyak-ke-banyak dengan antara Company
dan Person
dengan informasi tambahan tentang sifat hubungan. Jika saya mengimplementasikannya dalam Company
tabel, saya akan menggunakan nama kolom PresidentPersonID
dan TreasurerPersonID
untuk mempertahankan bagian * PersonID dari nama sambil menambahkan deskriptor tambahan. inner join Person as Presidents on Company.PresidentPersonID = Presidents.PersonID
Praktek menggunakan Id sebagai bidang kunci utama mengarah ke praktik di mana id ditambahkan ke setiap tabel. Banyak tabel sudah memiliki informasi unik yang secara unik mengidentifikasi catatan. Gunakan ITU sebagai kunci utama dan bukan bidang id yang Anda tambahkan ke setiap dan setiap tabel. Itu salah satu dasar dari basis data relasional.
Dan itulah mengapa menggunakan id adalah praktik yang buruk: id seringkali bukan hanya informasi peningkatan otomatis.
pertimbangkan tabel berikut:
PK id | Countryid | Countryname
1 | 840 | United States
2 | 528 | the Netherlands
Apa yang salah dengan tabel ini adalah bahwa hal itu memungkinkan pengguna untuk menambahkan baris lain: Amerika Serikat, dengan kode negara 840. Itu baru saja merusak integritas relasional. Ofcourse Anda dapat menerapkan keunikan pada masing-masing kolom, atau Anda bisa menggunakan kunci utama yang sudah tersedia:
PK Countryid | Countryname
840 | United States
528 | the Netherlands
Dengan begitu Anda menggunakan informasi yang sudah Anda miliki sebagai kunci utama, yang merupakan jantung dari desain basis data relasional.
Saya tidak berpikir itu praktik yang buruk jika digunakan dengan benar. Biasanya memiliki bidang ID penambahan-otomatis yang disebut "ID" yang tidak perlu Anda sentuh, dan gunakan pengenal yang lebih ramah untuk aplikasi tersebut. Mungkin sedikit merepotkan untuk menulis kode from tableA a inner join tableB b on a.id = b.a_id
tetapi kode itu dapat disimpan.
Sebagai preferensi pribadi saya cenderung awalan Id dengan nama entitas, tapi saya tidak melihat masalah nyata dengan hanya menggunakan Id
jika itu ditangani sepenuhnya oleh database.
ID cukup umum, yang menurut saya tidak akan membingungkan siapa pun. Anda akan selalu ingin tahu meja. Menempatkan nama bidang dalam kode produksi tanpa menyertakan tabel / alias adalah praktik yang buruk. Jika Anda terlalu khawatir untuk bisa mengetik pertanyaan ad hoc dengan cepat, Anda harus melakukannya sendiri.
Hanya berharap tidak ada yang mengembangkan database sql di mana ID adalah kata yang dilindungi undang-undang.
CREATE TABLE CAR (ID);
Mengurus kenaikan bidang nama, kunci utama, dan otomatis dengan 1 dimulai dengan 1 semua dalam satu paket 2 karakter kecil yang bagus. Oh, dan saya akan menyebutnya CARS tetapi jika kita akan menghemat stroke-key dan siapa yang benar-benar berpikir meja yang disebut CAR hanya akan memiliki satu?
Car
mewakili Table
tempat masing-masing Row
mewakili satu Car
. Memanggil Cars
perubahan semantik dan menunjukkan kurangnya pemahaman tentang prinsip dasar teori hubungan formal. Rails adalah contoh utama seseorang yang tahu cukup berbahaya .
Pertanyaan ini telah berulang kali dikalahkan, tetapi saya pikir saya juga akan menambahkan pendapat saya.
Saya menggunakan id yang berarti bahwa itu adalah pengidentifikasi untuk setiap tabel, jadi ketika saya bergabung ke sebuah tabel dan saya membutuhkan kunci primer saya secara otomatis bergabung ke kunci utama.
Bidang id adalah peningkatan otomatis, tidak ditandatangani (artinya saya tidak harus menetapkan nilainya dan tidak boleh negatif)
Untuk kunci asing, saya menggunakan tablenameid (sekali lagi masalah gaya), tetapi kunci utama yang saya ikuti adalah bidang id dari tabel, jadi konsistensi berarti saya selalu dapat memeriksa kueri dengan mudah
id juga pendek dan manis
Konvensi tambahan - gunakan huruf kecil untuk semua nama tabel dan kolom, jadi tidak ada masalah yang ditemukan karena kasus tersebut
Hal lain yang perlu dipertimbangkan adalah bahwa jika nama kunci utama berbeda dari nama kunci asing, maka tidak mungkin untuk menggunakan alat pihak ketiga tertentu.
Misalnya, Anda tidak akan dapat memuat skema Anda ke alat seperti Visio dan membuatnya menghasilkan ERD yang akurat.
Saya menemukan orang-orang di sini mencakup hampir setiap aspek tetapi saya ingin menambahkan bahwa "id" tidak dan tidak boleh dibaca sebagai "pengidentifikasi" itu lebih dari "indeks" dan tentu saja itu tidak menyatakan atau menggambarkan identitas baris. (Saya mungkin menggunakan kata-kata yang salah di sini, tolong perbaiki jika saya melakukannya)
Kurang lebih bagaimana orang membaca data tabel dan bagaimana mereka menulis kode mereka. Saya pribadi dan kemungkinan besar ini adalah cara paling populer yang saya lihat lebih sering adalah bahwa coders menulis referensi lengkap sebagai table.id
, bahkan jika mereka tidak perlu melakukan persatuan atau / dan bergabung. Sebagai contoh:
SELECT cars.color, cars.model FROM cars WHERE cars.id = <some_var>
Dengan begitu Anda dapat menerjemahkannya ke bahasa Inggris sebagai "Beri saya warna dan model mobil yang diberi nomor." dan bukan sebagai "Beri aku warna dan model mobil yang diidentifikasi sebagai angka." ID tidak mewakili mobil dengan cara apa pun, itu hanya indeks mobil, nomor seri jika Anda mau. Sama seperti ketika Anda ingin mengambil elemen ketiga dari array.
Jadi untuk meringkas apa yang ingin saya tambahkan adalah bahwa itu hanya masalah preferensi dan cara membaca SQL yang dijelaskan adalah yang paling populer.
Padahal, ada beberapa kasus di mana ini tidak digunakan, seperti (contoh yang jauh lebih langka) ketika ID adalah string yang benar-benar menggambarkan. Misalnya id = "RedFordMustang1970"
atau yang serupa. Saya sangat berharap saya bisa menjelaskan ini setidaknya untuk mendapatkan ide.