Apa cara yang efektif untuk memberi label pada kolom dalam basis data?

30

Saya dulu memberi label pada kolom di basis data saya seperti ini:

user_id
user_name
user_password_hash

Untuk menghindari konflik ketika bergabung dengan dua tabel, tetapi kemudian saya belajar lebih banyak tentang cara membuat tabel, dan saya berhenti melakukan ini.

Apa cara yang efektif untuk memberi label pada kolom dalam basis data? Mengapa?

Thomas O
sumber
Database yang mana? Bagaimana saya memberi label di Oracle berbeda dari kebanyakan database lain karena fitur itu secara otomatis memilih kolom untuk basis bergabung jika nama cocok.
Joe
@ Jo, Yah, saya selalu menggunakan MySQL dan SQLite3, tetapi seharusnya berlaku untuk sebagian besar database lainnya.
Thomas O
@ Jo tidak pernah memperhatikan bahwa Oracle berbeda. Bisakah Anda memberikan tautan?
bernd_k
@bernd_k: Saya telah menambahkan beberapa tautan ke jawaban saya , di bawah ini
Joe

Jawaban:

33

Dalam kasus Anda, pengguna awalan berlebihan. Kami (pengembang yang bertanggung jawab) tahu bahwa ini adalah pengguna tabel, jadi mengapa menambahkan user_awalan di depan setiap bidang?

Apa yang saya sarankan kepada Anda adalah melakukannya dengan pendekatan yang lebih alami.

Apa karakteristik seseorang: Nama Belakang, Nama Depan, Tanggal Lahir, Kebangsaan, dll ...

Apa karakteristik dari Mobil: Model, Tahun, Warna, Energi, dll ...

Kolom Anda harus dinamai sealami mungkin, itu akan membuat skema lebih jelas untuk semua orang, untuk Anda dan yang datang setelah Anda. Ini juga disebut fase Pemeliharaan, dan apa pun yang dapat Anda lakukan untuk membuat pemeliharaan lebih mudah biasanya sepadan dengan usaha.

Spredzy
sumber
1
Ya, itu membuat saya marah ketika orang melakukan itu. Juga ketika mereka memanggil semua tabel mereka tbl_apapun.
Gayus
Ini juga relevan dengan konsep "Kata-Kata Kelas", dan tampaknya ada beberapa perdebatan di komunitas ketika Kata-kata Kelas itu dan tidak sesuai. (kata kelas adalah alat untuk: Mengidentifikasi kategori atau klasifikasi data yang berbeda, Menggambarkan jenis data yang dijelaskan oleh nama data, dan Menjelaskan klasifikasi utama data yang terkait dengan elemen data.)
Jon Schoning
17

Selain komentar Spredzy, beri label kunci utama Anda sama (ID) sehingga ketika Anda menulis pertanyaan dengan cepat, Anda dapat dengan mudah mengingat (u.ID = c.ID) daripada harus mencari "Apakah itu countryID , country_ID, countries_ID, countriesID,? "

David Hall
sumber
5
Saya pernah bekerja pada database di mana DBA memutuskan untuk menggunakan ID di beberapa tabel dan id di yang lain dan kami telah mengatur MySQL untuk menjadi case-sensitive ... kali menyenangkan!
Toby
6
Kami biasanya menggunakan tablename.tablename_id. Misalnya car.car_id; person.person_id. Nama tunggal untuk tabel.
Glasnt
@glasnt keputusan yang cerdas.
garik
1
Ini sebenarnya ide yang sangat buruk, dan Anda akan kehilangan kemampuan untuk menggunakan USINGklausa SQL (itu bertentangan dengan spesifikasi).
Evan Carroll
9

Saya sangat setuju dengan tambahan David Hall untuk jawaban Spredzy yang luar biasa. Sederhana dan alami adalah cara untuk pergi. Kebingungan tabel seharusnya tidak menjadi masalah jika Anda memberi nama tabel secara alami juga.

Tidak masuk akal memiliki users.user_id dan cars.car_id ketika Anda bisa memiliki users.id dan cars.id

Bsoist
sumber
7

Saya berpendapat bahwa dalam skema database, setiap kolom harus memiliki nama yang unik, di seluruh tabel. Ada beberapa alasan untuk itu:

  • Dari sudut pandang pemodelan: Anda mulai dengan sup atribut dan Anda menormalkannya ke dalam tabel. Seiring waktu, Anda mungkin mendenormalisasi atau menormalkan lebih lanjut atau memperkenalkan pandangan atau pandangan terwujud, atau memperkenalkan tabel baru. Ini tidak pernah menjadi masalah jika semua nama kolom unik.

  • Anda dapat menggunakan ini bergabung sintaks: a JOIN b USING (a_id) JOIN c USING (a_id). Sangat nyaman dan juga membantu dengan poin berikut.

  • Jika Anda menjalankan kueri dengan banyak gabungan atau membuat tampilan terwujud dengan SELECT *, Anda tidak akan pernah (yah, mungkin jarang) memiliki konflik. Pikirkan tentang bergabung person.name, product.name, country.name, dll Urgh.

  • Secara umum, jika Anda memiliki pertanyaan besar, sulit untuk melacak apa idartinya di mana-mana.

Peter Eisentraut
sumber
Bagaimana Anda memberi nama kolom untuk nama karyawan dan nama situs misalnya? Bagaimana Anda menghindari redundansi kolom label nama?
Spredzy
@ Spredzy: Saya hanya akan pergi dengan redundansi.
Peter Eisentraut
1
Jawaban untuk masalah ini: alias.
Jon of All Trades
7

Mari kita lihat, dengan contoh Anda akan terlihat seperti ini:

USERS
----
id
username,
password
registration_date

Saya menggunakan nama tabel dalam huruf besar. Ini memungkinkan saya mengidentifikasi tabel dengan mudah. Kolom yang baru saya beri nama adalah masing-masing untuk apa yang diwakilinya. Saya mencoba untuk tidak menggunakan angka atau memasukkan awalan atau akhiran dengannya. Ini akan membuat kueri mati sederhana dan sangat mudah.

BTW, saya pikir Anda harus menemukan beberapa gaya yang Anda sukai dan tetap menggunakannya. Jika Anda sering mengubahnya, maka Anda akan memiliki skema DB yang berantakan.

eiefai
sumber
+1 untuk "temukan beberapa gaya yang kamu suka dan tetap menggunakannya." Konsistensi lebih baik daripada mematuhi standar tertentu (meskipun jika Anda belum memilih standar, beberapa lebih baik daripada yang lain).
Jon of All Trades
5

Seperti yang lain, saya sarankan Anda tidak memasukkan nama tabel sebagai bagian dari kolom. Kecuali jika Anda memiliki ratusan tabel semua dengan nama kolom yang hampir sama: jika Anda memiliki beberapa lusinan tabel semua dengan kolom berjudul ID, maka tentu saja awali mereka dengan nama tabel.

Saya baru-baru ini meninggalkan perusahaan di mana salah satu pengembang lebih suka awalan kolom kunci utama dan kunci asing dengan pk dan fk. Ini mengarah ke beberapa kekejian di mana kolom dimulai dengan pkfk (biasanya kunci primer komposit berdasarkan 2 kolom, di mana satu kolom adalah kunci asing ke tabel lain).

Tangurena
sumber
4
apakah itu dianggap sebagai fk_cluster?
Kaji
5

Saya bekerja di lingkungan di mana setiap nama kolom dimulai dengan awalan yang berasal dari nama tabel, itu bukan penemuan saya, tapi saya cukup senang dengannya.

Idealnya, nama kolom unik untuk semua tabel dalam database.

Beberapa pengamatan:

  • kita hanya perlu alias tabel, ketika tabel digabungkan beberapa kali dalam pernyataan pilih
  • itu mencegah beberapa kesalahan saat menyalin cuplikan kode, karena nama kolom harus disesuaikan dengan nama tabel
  • ini membantu untuk menunjukkan ke tabel mana kolom poin kunci asing

Gagasan umum: Yang paling penting adalah konsistensi dari setiap konvensi penamaan: - tunggal vs jamak (ok yang berlaku untuk tabel dan bukan kolom) - mengidentifikasi kunci utama dan asing (mereka membangun struktur vs isi database) - konsisten ketika Anda menyimpan string dan varian pendek dari string yang sama - konsisten dengan flag, status, dll.

bernd_k
sumber
3

Saya setuju dengan jawaban Spredzy tetapi akan menambahkan bahwa sebagai pilihan saya akan menggunakan camelCase daripada under_score.

firstName, lastName dll.

Toby
sumber
2
-1 karena CamelCase tidak berfungsi di semua sistem basis data dan Anda tidak menentukan sistem basis data. Sebagai contoh, berita buruknya untuk menggunakan CamelCase di Oracle (akan membutuhkan penggunaan tanda kutip ganda untuk membuatnya, tetapi sejak saat itu, semua orang yang mengaksesnya harus melewati rintangan untuk mengakses / menggunakannya). Sungguh mimpi buruk.
ScottCher
@ScottCher - Saya tidak tahu bahwa itu tidak berfungsi di Oracle, tapi kemudian saya bukan Oracle DBA. Saya akan berpikir itu akan dianggap sebagai mengingat bahwa nama kolom pertama harus mematuhi aturan yang ditetapkan oleh DBS yang bersangkutan.
Toby
3

Dalam kasus Oracle, Anda akan ingin tidak nama kolom 'id' atau 'name' atau apa pun yang generik.

Masalahnya adalah bahwa secara default di versi yang lebih lama , Oracle akan mencoba untuk bergabung dengan tabel berdasarkan nama kolom yang sama, jadi jika saya telah menamai semuanya dengan baik, maka saya juga akhirnya menentukan klausa gabungan default di antara tabel saya.

Tetapi bahkan jika Anda tidak menggunakan Oracle, dengan tidak memilih nama yang muncul dalam beberapa tabel, itu juga berarti bahwa Anda tidak harus melalui masalah peng aliasing setiap kali Anda harus melakukan pemilihan di dua tabel:

SELECT
  instrument.name as instrument_name,
  instrument.abbr as instrument_abbr,
  source.name     as source_name,
  source.abbr     as source_abbr,
  ...
FROM ...

Jadi, jika pilihan multi-tabel adalah norma, nama kolom yang lebih lama menghemat Anda mengetik. (jika Anda hanya menggunakan satu tabel pada satu waktu ... apakah Anda benar-benar membutuhkan database relasional?)

... dan penghematan pengetikan membawa kita ke masalah lain di Oracle - setidaknya dalam 8i (versi saat ini ketika saya mengambil kursus Oracle SQL Tuning dan Pemodelan Data) caching rencana eksekusi hanya didasarkan pada begitu banyak karakter pertama dari kueri (tidak dapat mengingat nilai pastinya ... 1024?), jadi jika Anda memiliki kueri yang hanya bervariasi menurut sesuatu di akhir klausa di mana, dan daftar kolom yang Anda ekstraksi sangat panjang, Anda dapat mengalami hit kinerja karena tidak dapat men-cache rencana eksekusi dengan benar.

Oracle memiliki panduan dalam memilih apa yang mereka klaim adalah nama tabel dan kolom yang baik, yang pada dasarnya adalah panduan untuk menghapus huruf sampai sekitar 5-8 karakter, tetapi saya tidak pernah terlalu memperhatikannya.

...

Yang terjadi selain itu:

  • kolom selalu tunggal (tabel selalu jamak)
  • semua nama huruf kecil, kalau-kalau ada sesuatu yang sensitif huruf
  • sebagai akibat dari hal di atas, gunakan garis bawah alih-alih kasing unta.

pembaruan : bagi mereka yang tidak terbiasa dengan perilaku bergabung Oracle, lihat contoh terakhir tentang Menguasai Oracle SQL: Gabung Ketentuan , di mana disebutkan:

Apa yang terjadi? Alasannya terletak pada fakta bahwa, selain dari supplier_id, kedua tabel ini memiliki pasangan kolom lain dengan nama yang sama. Kolom itu adalah nama. Jadi, ketika Anda meminta gabungan alami antara pemasok dan tabel bagian, bergabung terjadi tidak hanya dengan menyamakan kolom supplier_id dari dua tabel, tetapi kolom nama dari dua tabel disamakan juga. Karena, tidak ada nama pemasok yang sama dengan nama bagian dari pemasok yang sama, tidak ada baris yang dikembalikan oleh permintaan.

Di bawah 'old join syntax' (8i dan sebelumnya), 'NATURAL JOIN' adalah perilaku join default, dan saya yakin itu masih terjadi jika Anda tidak menentukan kondisi join. Setelah 'NATURAL JOIN' adalah opsi resmi di 9i, rekomendasi umum adalah jangan menggunakannya , karena penamaan kolom yang buruk dapat mengacaukan Anda, yang mana saya menganjurkan nama kolom yang bagus.

Joe
sumber
4
Anda mengacu pada "Natural Joins" di paragraf kedua Anda? Jika demikian, SHUDDER ... Kapan pun memungkinkan, Anda harus menentukan bagaimana Anda ingin sistem basis data Anda bergabung dengan tabel Anda. Membiarkannya hingga ke database untuk memutuskan dapat menghasilkan hasil yang tidak terduga / tidak konsisten. Selain itu, Natural Joins terbatas pada join antara dua tabel dan dengan demikian relatif terbatas dalam kegunaannya.
ScottCher
2
GABUNG ALAMI tidak pernah menjadi default. Jika tidak ada gabungan yang eksplisit / diberikan, gabungan kartesius akan dilakukan (yaitu masing-masing dan setiap baris dalam tabel yang bergabung dengan masing-masing dan setiap baris dalam tabel lainnya). Sebelum ANSI bergabung didukung (yaitu yang ditentukan dalam klausa FROM) bergabung harus dilakukan dalam klausa WHERE.
Gary
1
-1 untuk gabungan alami. Ketika perubahan skema yang tidak terkait dapat memutuskan bergabung, atau lebih buruk lagi, mengubahnya tanpa menyebabkan kesalahan, Anda berada dalam dunia yang penuh kesakitan. Tolong, pikirkan anak-anak, dan SELALU tentukan bidang gabung Anda.
Jon of All Trades
2
@ScottCher: "Meninggalkannya ke database untuk memutuskan" - pertama, mungkin maksudmu "DBMS" daripada "database". Kedua, tidak ada mekanisme AI atau antropomorfistik di Oracle; melainkan NATURAL JOINdeterministik.
onedaywhen
1
@Joe cross joinadalah, tadinya dan akan selalu menjadi 'default'. Oracle tidak pernah cocok dengan nama kolom kecuali jika natural joinsecara eksplisit digunakan
Jack Douglas
1
  1. Jangan pernah gunakan tanda kutip ganda " karena dengan melakukan itu, Anda menimpa case-fold asli dari database. SQL spec menuntut semua pengidentifikasi dilipat ke huruf besar. Beberapa database, seperti PostgreSQL, melipatnya menjadi huruf kecil. Jika tidak ada yang dikutip, ini akan bekerja di semua database dan mereka dapat melipatnya ke spec atau default khusus rdbms.
  2. Gunakan under_score ( _), karena seperti di atas - Anda tidak boleh menggunakan camelCase.
  3. gunakan {entity}_iduntuk id (dan kunci asing yang menunjuk ke id itu). Karena dengan begitu Anda dapat menggunakan USINGklausa. Nama-nama kunci unik-global yang digunakan dalam kondisi gabungan adalah konvensi yang ditetapkan dalam spesifikasi.

    SELECT *
    FROM employee
    INNER JOIN department
      USING (department_id);
    
      -- compare to
      ON employee.department_id = department.department_id;
Neil McGuigan
sumber
1
Saya memperbarui ini agar lebih eksplisit.
Evan Carroll