Kunci utama Sqlite pada banyak kolom


Jawaban:


805

Menurut dokumentasi , itu

CREATE TABLE something (
  column1, 
  column2, 
  column3, 
  PRIMARY KEY (column1, column2)
);

3
Yah, ini benar, tetapi menurut dokumentasi, CREATE TABLE sesuatu (kolom1 KUNCI UTAMA, kolom2 KUNCI UTAMA); harus dimungkinkan juga, tetapi tidak.
Yar

6
@Yar Docs mengatakan "Jika ada lebih dari satu klausa PRIMARY KEY dalam satu pernyataan CREATE TABLE, itu adalah kesalahan." Ya, diagram jalur kereta api mungkin menunjukkan yang valid juga, tetapi teks di bawah ini mengklarifikasi tidak.
Brian Campbell

10
Ingatlah untuk menambahkan bagian KUNCI UTAMA (kolom1, kolom2) di akhir seperti pada jawaban ini. Jika Anda mencoba menambahkannya setelah definisi kolom2 Anda akan mendapatkan kesalahan sintaksis .
vovahost

159
CREATE TABLE something (
  column1 INTEGER NOT NULL,
  column2 INTEGER NOT NULL,
  value,
  PRIMARY KEY ( column1, column2)
);

Bukankah Primary Key memaksakan NOT NULL?
pratnala

23
@ratnala Dalam SQL standar, ya. Dalam SQLite, NULLdiizinkan di kunci utama. Jawaban ini menekankan bahwa jika Anda menginginkan perilaku yang lebih standar, Anda perlu menambahkan NOT NULLdiri Anda sendiri. Jawaban saya hanyalah sintaks yang sangat mendasar untuk kunci primer multi-kolom.
Brian Campbell

42

Iya. Tetapi ingat bahwa kunci utama tersebut memungkinkan NULLnilai di kedua kolom beberapa kali.

Buat tabel seperti itu:

    sqlite> CREATE TABLE something (
column1, column2, value, PRIMARY KEY (column1, column2));

Sekarang ini berfungsi tanpa peringatan:

sqlite> insert into something (value) VALUES ('bla-bla');
sqlite> insert into something (value) VALUES ('bla-bla');
sqlite> select * from something;
NULL|NULL|bla-bla
NULL|NULL|bla-bla

Apakah ada referensi untuk alasan perilaku seperti itu? Apa cara yang baik untuk membuang beberapa baris dalam database dan masih menghapus duplikat, bahkan jika mengandung NULL?
Pastafarianis

4
@Pastafarianist sqlite.org/lang_createtable.html - "Menurut standar SQL, PRIMARY KEY harus selalu menyiratkan TIDAK NULL. Sayangnya, karena bug dalam beberapa versi awal, ini bukan kasus di SQLite. [...] NULL nilai dianggap berbeda dari semua nilai lainnya, termasuk NULL lainnya. "
Jan

Ya, dalam SQL NULLs selalu membandingkan false. Karena itu, teori relasional secara khusus mengecualikan NULL sebagai nilai komponen kunci apa pun. SQLite, bagaimanapun, adalah praktik relasional. Tampaknya penulis memilih untuk secara pragmatis mengizinkan beberapa tetapi tidak "sama" kunci. Jelas itu lebih baik untuk tidak membiarkan NULL sebagai nilai kunci.
holdenweb

31

Dasar:

CREATE TABLE table1 (
    columnA INTEGER NOT NULL,
    columnB INTEGER NOT NULL,
    PRIMARY KEY (columnA, columnB)
);

Jika kolom Anda adalah kunci asing dari tabel lain (kasus umum):

CREATE TABLE table1 (
    table2_id INTEGER NOT NULL,
    table3_id INTEGER NOT NULL,
    FOREIGN KEY (table2_id) REFERENCES table2(id),
    FOREIGN KEY (table3_id) REFERENCES table3(id),
    PRIMARY KEY (table2_id, table3_id)
);

CREATE TABLE table2 (
    id INTEGER NOT NULL,
    PRIMARY KEY id
);

CREATE TABLE table3 (
    id INTEGER NOT NULL,
    PRIMARY KEY id
);

14

Bidang kunci primer harus dinyatakan sebagai bukan nol (ini bukan standar karena definisi kunci primer adalah bahwa ia harus unik dan bukan nol). Tetapi di bawah ini adalah praktik yang baik untuk semua kunci utama multi-kolom dalam DBMS apa pun.

create table foo
(
  fooint integer not null
  ,foobar string not null
  ,fooval real
  ,primary key (fooint, foobar)
)
;

11

Sejak versi 3.8.2 dari SQLite, sebuah alternatif untuk spesifikasi NOT NOT NULL adalah spesifikasi "TANPA ROWID": [ 1 ]

NOT NULL is enforced on every column of the PRIMARY KEY
in a WITHOUT ROWID table.

Tabel "TANPA ROWID" memiliki potensi keuntungan efisiensi, jadi alternatif yang kurang tepat untuk dipertimbangkan adalah:

CREATE TABLE t (
  c1, 
  c2, 
  c3, 
  PRIMARY KEY (c1, c2)
 ) WITHOUT ROWID;

Misalnya, pada prompt sqlite3: sqlite> insert into t values(1,null,3); Error: NOT NULL constraint failed: t.c2


Bagi siapa pun yang membaca ini saat ini: WITHOUT ROWIDmemiliki implikasi tambahan, dan itu tidak boleh digunakan sebagai alternatif untuk menulis di NOT NULLsebelah kunci utama Anda.
shadowtalker


2

PRIMARY KEY (id, name)tidak bekerja untuk saya. Menambahkan kendala sebagai gantinya melakukan pekerjaan.

CREATE TABLE IF NOT EXISTS customer (id INTEGER, name TEXT, user INTEGER, CONSTRAINT PK_CUSTOMER PRIMARY KEY (user, id))


1

Kode berikut membuat tabel dengan 2 kolom sebagai kunci utama dalam SQLite.

LARUTAN:

CREATE TABLE IF NOT EXISTS users (id TEXT NOT NULL, name TEXT NOT NULL, pet_name TEXT, PRIMARY KEY (id, name))
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.