Mengapa tabel menggunakan kunci utamanya sebagai kunci asing untuk dirinya sendiri

21

Melihat melalui database, saya menemukan sebuah tabel yang menggunakan kunci utamanya sebagai kunci asing untuk dirinya sendiri.

Saya telah melihat bahwa sebuah tabel dapat memiliki kunci asing untuk dirinya sendiri untuk membangun struktur hierarki, tetapi akan menggunakan kolom lain untuk referensi kunci utama.

Karena kunci utama itu unik, dalam situasi ini bukankah baris hanya dapat menunjuk kembali ke dirinya sendiri? Itu tampaknya merupakan tautan tautologis, karena jika saya sudah memiliki baris, maka saya sudah memiliki baris.

Apakah ada alasan mengapa hal ini dilakukan?

Tabel bergabung dengan dirinya sendiri

Saya yakin batasannya ditulis seperti itu (tidak hanya melihat diagram) karena tabel dan kolom yang sama digunakan untuk kedua bagian definisi.

Aaroninus
sumber
6
Mungkin melalui penggunaan tangan-tangan dari perancang adalah teori saya
Martin Smith

Jawaban:

28

Seperti yang kamu katakan. Sebuah FOREIGN KEYkendala referensi meja yang sama biasanya untuk struktur hirarki dan itu akan menggunakan kolom lain untuk referensi kunci utama. Contoh yang baik adalah tabel karyawan:

EmployeeId    Int     Primary Key
EmployeeName  String
ManagerId     Int     Foreign key going back to the EmployeeId

Jadi dalam hal ini ada kunci asing dari tabel kembali ke dirinya sendiri. Semua manajer adalah juga karyawan sehingga ManagerIdsebenarnya adalah EmployeeIdmilik manajer.

Sekarang di sisi lain jika Anda bermaksud seseorang menggunakan EmployeeIdkunci asing kembali ke tabel Karyawan maka itu mungkin kesalahan . Saya memang menjalankan tes dan itu mungkin tetapi tidak akan ada gunanya nyata.

CREATE TABLE Employee (EmployeeId Int PRIMARY KEY,
                        EmployeeName varchar(50),
                        ManagerId Int);


ALTER TABLE Employee ADD CONSTRAINT fk_employee 
    FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId);
Kenneth Fisher
sumber
1
Menempatkan batasan pada ManagerId yang terkait dengan EmployeeId dalam hal ini dapat bermanfaat jika Palungan harus "dipisahkan". Itu tidak akan mengizinkan penghapusan baris jika diatur seperti itu. Tidak mengatakan saya akan melakukannya dengan cara itu tetapi bisa bermanfaat jika aplikasi Anda bergantung pada karyawan yang memiliki manajer.
zgr024
6

Saya baru saja menemukan kunci asing di db saya sendiri dan pasti saya sendiri yang membuatnya. Saya pikir ini baru saja terjadi secara kebetulan. Jika saya mengklik "Kunci Asing Baru" di menu konteks tabel dengan kunci utama (dalam Management Studio, SQL 2014 Express) ini sudah secara otomatis membuat kunci asing seperti itu merujuk pada dirinya sendiri. Lihat di bawah:

masukkan deskripsi gambar di sini

Jika saya kemudian tidak menyadari bahwa saya harus mengubah yang itu alih-alih menambahkan yang baru, itu akan tetap ada. Atau, jika saya cukup klik pada tombol [Tutup] yang berarti ini akan seperti [Batal], kunci asing masih akan dibuat setelah menyimpan definisi tabel.

Jadi, bagi saya Kunci Asing seperti itu tidak masuk akal dan dapat dihapus.

Stefan Müller
sumber
Mungkin saja Anda ingin membuat FK dan dalam proses Anda menyadari bahwa tabel lain belum menetapkan PK-nya, maka Anda membatalkan, pergi ke meja lainnya dan kemudian karena alasan tertentu Anda lupa untuk melanjutkan proses FK. Di sana Anda memiliki FK rekursif Anda.
Andrew
4

Mungkin desainer ingin menonaktifkan penggunaan TRUNCATE TABLE?

TRUNCATE TABLEtidak dapat digunakan pada tabel dengan batasan kunci asing ke tabel lain meskipun itu dapat digunakan jika ada kunci asing referensial sendiri . Dari dokumentasi untuk TRUNCATE TABLE (Transact-SQL) :

Ekstrak BOL

Sebuah DELETEpernyataan tanpa WHEREklausa memiliki efek mirip dengan TRUNCATE TABLE(menghapus semua baris dalam tabel) tetapi DELETEpernyataan kebakaran pemicu menghapus, yang mungkin menjadi alasan untuk memungkinkan DELETEtapi tidak TRUNCATE TABLE.

Saya akan melakukan ini dengan menggunakan izin ( DELETEmemerlukan izin hapus, TRUNCATE TABLEmemerlukan izin mengubah tabel), tetapi mungkin ada beberapa alasan perancang tidak dapat melakukan ini?

Catatan: Meskipun apa yang telah dilakukan perancang sebenarnya tidak menonaktifkan penggunaan TRUNCATE TABLE, saya masih berspekulasi bahwa ini adalah maksud mereka.

Greenstone Walker
sumber