Skema penamaan Kunci Asing

153

Saya baru mulai bekerja dengan kunci asing untuk pertama kalinya dan saya bertanya-tanya apakah ada skema penamaan standar yang digunakan untuk mereka?

Diberikan tabel ini:

task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)

Di mana Tugas memiliki Catatan, Tugas dimiliki oleh Pengguna, dan Catatan penulis Pengguna.

Bagaimana ketiga kunci asing akan disebutkan dalam situasi ini? Atau sebagai alternatif, apakah itu penting ?

Pembaruan : Pertanyaan ini tentang nama kunci asing, bukan nama bidang!

nickf
sumber
6
Catatan untuk pembaca: Banyak praktik terbaik yang tercantum di bawah ini tidak berfungsi di Oracle karena batas nama 30 karakternya. Nama tabel atau nama kolom mungkin sudah mendekati 30 karakter, jadi konvensi yang menggabungkan keduanya menjadi satu nama memerlukan standar pemotongan atau trik lainnya.
Charles Burns
Kemungkinan duplikat penamaan kolom ID dalam tabel database
philipxy

Jawaban:

180

Konvensi standar dalam SQL Server adalah:

FK_ForeignKeyTable_PrimaryKeyTable

Jadi, misalnya, kunci antara catatan dan tugas adalah:

FK_note_task

Dan kunci antara tugas dan pengguna adalah:

FK_task_user

Ini memberi Anda pandangan 'sekilas pandang' dari tabel mana yang terlibat dalam kunci, sehingga membuatnya mudah untuk melihat tabel mana yang satu (yang pertama bernama) tergantung pada (yang kedua bernama). Dalam skenario ini, set kunci lengkap adalah:

FK_task_user
FK_note_task
FK_note_user

Jadi, Anda dapat melihat bahwa tugas bergantung pada pengguna, dan catatan bergantung pada tugas dan pengguna.

Greg Beech
sumber
1
Jika kunci asing menunjuk ke kunci kandidat pada tabel kedua daripada kunci primer, maka Anda mungkin akan menggunakan segmen ketiga untuk nama untuk memenuhi syarat ini. Ini adalah situasi yang tidak biasa, dan bukan yang biasanya Anda desain dari awal, jadi saya tidak memasukkan ini dalam respons.
Greg Beech
4
Anda memasukkan nama tabel saat ini di kunci untuk membuatnya berbeda. Nama-nama FK ada dalam namespace global dalam SQL Server sehingga Anda tidak dapat memiliki dua FK bernama FK_PrimaryKeyTable terlampir pada dua tabel kunci asing yang berbeda. Aturan mungkin berbeda untuk server database lain.
Greg Beech
Oke ... Saya memiliki ruang nama yang berbeda untuk setiap tabel di Oracle, jadi saya tidak perlu referensi sendiri.
Steve Moyer
29
Ini tampaknya menjadi penggunaan umum tetapi apa yang dilakukan orang ketika ada dua kunci asing menunjuk ke tabel yang sama. yaitu messagetabel memiliki from_user_iddan to_user_idkeduanya akan menjadi fk_message_user. Menurut saya lebih baik menggunakan fk_tablename_columnname(fk_message_from_user_id dalam contoh saya) untuk alasan ini dan kemudian mencoba untuk menjaga nama kolom Anda jelas tentang tabel target (yaitu to_user_id jelas merujuk ke tabel pengguna)
Code Commander
bagaimana jika kedua tabel itu sendiri memiliki garis bawah untuk ex. user_role dan user_addresses? fk_user_addresses_user_role bukankah membingungkan?
Govi S
38

Saya menggunakan dua karakter garis bawah sebagai pembatas yaitu

fk__ForeignKeyTable__PrimaryKeyTable 

Ini karena nama tabel terkadang mengandung karakter garis bawah itu sendiri. Ini mengikuti konvensi penamaan untuk kendala umumnya karena nama elemen data akan sering berisi karakter garis bawah misalnya

CREATE TABLE NaturalPersons (
   ...
   person_death_date DATETIME, 
   person_death_reason VARCHAR(30) 
      CONSTRAINT person_death_reason__not_zero_length
         CHECK (DATALENGTH(person_death_reason) > 0), 
   CONSTRAINT person_death_date__person_death_reason__interaction
      CHECK ((person_death_date IS NULL AND person_death_reason IS NULL)
              OR (person_death_date IS NOT NULL AND person_death_reason IS NOT NULL))
        ...
suatu hari nanti
sumber
3
Ini benar-benar jawaban terbaik.
Frederik Krautwald
1
Saya baru saja membuat Derby DB dengan konvensi penamaan yang sangat spesifik dan yang ini adalah yang paling mudah dibaca dan dapat dilacak. Terima kasih
Anddo
17

Bagaimana dengan FK_TABLENAME_COLUMNNAME?

K eep Aku t S imple S tupid bila memungkinkan.

EvilTeach
sumber
20
Karena ketika Anda memiliki db besar dengan banyak kunci dan tabel dan Anda mendapatkan kesalahan selama pembaruan skema di perangkat lunak Anda, cukup sulit untuk menemukan di mana kunci asing bahkan didefinisikan tanpa melakukan pencarian dari database membuat skrip.
JohnC
1
@ JohnC jika nama kolom FK memiliki nama tabel lain dalam nama kolom maka bukankah mudah untuk mengatakannya? Ini memberi tahu Anda dua tabel dan nama kolom yang didefinisikan. Contoh: FK_Animals_OwnerID—Animal dan Pemilik tabel, didefinisikan pada kolom
OwnerID
10

Catatan dari Microsoft tentang SQL Server:

Batasan KUNCI ASING tidak harus dikaitkan hanya dengan batasan KUNCI UTAMA di tabel lain; itu juga dapat didefinisikan untuk referensi kolom dari batasan UNIK di tabel lain.

jadi, saya akan menggunakan istilah yang menggambarkan ketergantungan alih-alih istilah hubungan primer / asing konvensional.

Saat mereferensikan KUNCI UTAMA dari tabel (orang tua) independen dengan kolom dengan nama yang sama di tabel anak (dependen) , saya menghilangkan nama kolom:

FK_ChildTable_ParentTable

Saat mereferensikan kolom lain, atau nama kolom bervariasi antara dua tabel, atau hanya untuk menjadi eksplisit:

FK_ChildTable_childColumn_ParentTable_parentColumn
bvj
sumber
9

Saya biasanya hanya meninggalkan PK saya bernama id, dan kemudian menyatukan nama tabel dan nama kolom kunci saya ketika menamai FK di tabel lain. Saya tidak pernah repot-repot dengan unta-casing, karena beberapa database membuang sensitivitas huruf dan tetap mengembalikan semua nama huruf besar atau kecil. Bagaimanapun, inilah versi tabel saya yang akan terlihat:

task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);

Perhatikan bahwa saya juga memberi nama tabel saya dalam bentuk tunggal, karena satu baris mewakili salah satu objek yang saya tekankan. Banyak dari kebaktian ini adalah pilihan pribadi. Saya menyarankan bahwa lebih penting untuk memilih konvensi dan selalu menggunakannya, daripada mengadopsi konvensi orang lain.

Steve Moyer
sumber
heh - ini adalah gaya yang sebenarnya saya gunakan (tetapi dengan camelCase) - Saya pikir saya akan menambahkan sedikit deskripsi tambahan ke dalam nama-nama untuk tujuan menggambarkan hubungan mereka.
nickf
Jadi setidaknya kita bisa membaca skema masing-masing;) ... apa yang memalukan adalah tidak bisa membaca sendiri setelah beberapa tahun absen. Kami menggunakan ERWin untuk membuat diagram skema kami, tetapi seringkali nyaman untuk memiliki versi teks dan memiliki konvensi, mari Anda menemukan tabel dan bidang dengan mudah.
Steve Moyer
5

Ini mungkin over-kill, tetapi ini bekerja untuk saya. Ini sangat membantu saya ketika saya berurusan dengan VLDB khususnya. Saya menggunakan yang berikut ini:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

Tentu saja jika karena alasan tertentu Anda tidak mereferensikan kunci utama Anda harus mereferensikan sebuah kolom yang terkandung dalam batasan unik, dalam hal ini:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

Bisakah ini panjang, ya. Apakah itu membantu menjaga informasi agar tetap jelas untuk laporan, atau membuat saya lompatan cepat bahwa masalah potensial adalah selama peringatan 100% akan senang untuk mengetahui pikiran orang-orang tentang konvensi penamaan ini.

SSISPissesMeOff
sumber
1

Pendekatan saya yang biasa

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

Atau dengan istilah lain

FK_ChildColumnName_ParentTableName_ParentColumnName

Dengan cara ini saya bisa memberi nama dua kunci asing yang mereferensikan tabel yang sama seperti history_info tabledengan column actionBy and actionTodari dari users_infotabel

Itu akan seperti

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

Perhatikan bahwa:

Saya tidak memasukkan nama tabel anak karena tampaknya masuk akal bagi saya, saya ada di tabel anak sehingga saya dapat dengan mudah menganggap nama tabel anak itu. Total karakternya adalah 26 dan cocok dengan batas 30 karakter oracle yang dinyatakan oleh Charles Burns pada komentar di sini

Catatan untuk pembaca: Banyak praktik terbaik yang tercantum di bawah ini tidak berfungsi di Oracle karena batas nama 30 karakternya. Nama tabel atau nama kolom mungkin sudah mendekati 30 karakter, jadi konvensi yang menggabungkan keduanya menjadi satu nama memerlukan standar pemotongan atau trik lainnya. - Charles Burns

Cary Bondoc
sumber
Meja Anda akan gagal jika Anda memiliki tabel ke-3 dan memiliki titik FK ke ParentTableName_ParentColumnName tabel yang sama dengan menduplikasi FK_Name
Tony Dong
0

Berdasarkan jawaban dan komentar di sini, konvensi penamaan yang meliputi tabel FK, bidang FK, dan tabel PK (FK_FKTbl_FKCol_PKTbl) harus menghindari tabrakan nama kendala FK.

Jadi, untuk tabel yang diberikan di sini:

fk_task_userid_user
fk_note_userid_user

Jadi, jika Anda menambahkan kolom untuk melacak siapa yang terakhir memodifikasi tugas atau catatan ...

fk_task_modifiedby_user
fk_note_modifiedby_user
Chad Kieffer
sumber
-2

Jika Anda tidak mereferensikan FK Anda sesering itu dan menggunakan MySQL (dan InnoDB) maka Anda bisa membiarkan MySQL memberi nama FK untuk Anda.

Di lain waktu Anda dapat menemukan nama FK yang Anda butuhkan dengan menjalankan kueri .

pengguna12345
sumber
4
Saya hanya bisa menjelaskan suara saya. Hampir setiap sistem basis data memungkinkan sistem untuk menyebutkan batasan, Dapatkah Anda bayangkan kembali dan mencoba mencari tahu dengan cepat selama masalah produksi dengan basis data 100 tabel, mencoba menguraikan hubungan apa yang terkait dengan FK__123ee456ff? Itu sederhana dan cukup menerapkan praktik MENGERIKAN. Ketika Anda membuat indeks pada FK ini, lalu bagaimana? nama sistem itu juga? jadi ketika indeks IX_007e373f5963 adalah 98% terfragmentasi bagaimana Anda tahu di mana harus mencari tahu mengapa? Seharusnya tidak dilakukan.
SSISPissesMeOff
-3

Coba gunakan UUID Versi 4 yang berhuruf besar dengan oktet pertama diganti oleh FK dan '_' (garis bawah) alih-alih '-' (tanda hubung).

Misalnya

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

Dasar pemikirannya adalah sebagai berikut

  • Algoritma generasi ketat => nama yang seragam ;
  • Panjang kunci kurang dari 30 karakter , yang merupakan batasan panjang penamaan di Oracle (sebelum 12c);
  • Jika nama entitas Anda berubah, Anda tidak perlu mengganti nama FK Anda seperti dalam pendekatan berbasis entitas-nama (jika DB mendukung operator ganti nama tabel);
  • Orang jarang menggunakan nama batasan kunci asing. Misalnya alat DB biasanya menunjukkan batasan apa yang berlaku. Tidak perlu takut dengan tampilan samar, karena Anda dapat menghindari menggunakannya untuk "dekripsi".
kesedihan
sumber