Kunci utama Sqlite pada banyak kolom

Jawaban:

805

Menurut dokumentasi , itu

CREATE TABLE something (
  column1, 
  column2, 
  column3, 
  PRIMARY KEY (column1, column2)
);
Brian Campbell
sumber
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)
);
xiwok
sumber
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
jsmarkus
sumber
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
);
compte14031879
sumber
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)
)
;
Ken Reed
sumber
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

puncak
sumber
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

Dalam cara lain, Anda juga dapat membuat dua kolom kunci utama unique dan auto-increment kunci primary. Sama seperti ini: https://stackoverflow.com/a/6157337

ElonChan
sumber
Inilah yang sebenarnya saya cari. Terima kasih!
Swadhikar C
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))

Choxmi
sumber
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))
Naveen Kumar V
sumber