Birden çok sütunda sqlite birincil anahtarı


Yanıtlar:


805

Belgelere göre ,

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

3
Peki, bu doğru, ama belgelere göre, bir şey TABLO OLUŞTUR (sütun1 BİRİNCİL ANAHTAR, sütun2 BİRİNCİL ANAHTAR); de mümkün olmalı, ama değil.
Yar

6
@Yar Dokümanlar "Tek bir CREATE TABLE deyiminde birden fazla PRIMARY KEY yan tümcesi varsa, bu bir hatadır." Evet, demiryolu diyagramları bunun da geçerli olduğunu gösterebilir, ancak aşağıdaki metin bunun geçerli olmadığını açıklığa kavuşturur.
Brian Campbell

10
Bu cevaptaki gibi PRIMARY KEY (sütun1, sütun2) bölümünü eklemeyi unutmayın . Sütun2 tanımından sonra eklemeye çalışırsanız, bir sözdizimi hatası alırsınız .
vovahost

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

Birincil Anahtar NULL DEĞİL vermez mi?
pratnala

23
@pratnala Standart SQL'de evet. SQLite'de NULLbirincil anahtarlarda izin verilir. Bu cevap, daha standart davranışlar istiyorsanız, NOT NULLkendinizi eklemeniz gerektiğini vurgulamaktadır . Cevabım, çok sütunlu birincil anahtarın temel sözdizimidir.
Brian Campbell

42

Evet. Ancak, bu tür birincil anahtarın NULLher iki sütundaki değerlere birden çok kez izin verdiğini unutmayın .

Aşağıdaki gibi bir tablo oluşturun:

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

Şimdi bu herhangi bir uyarı olmadan çalışır:

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

Bu tür davranışların nedenine ilişkin herhangi bir referans var mı? İçerdiler bile veritabanındaki birkaç satırı dökmenin ve yinelenenleri kaldırmanın iyi bir yolu nedir NULL?
Pastafarianist

4
@Pastafarianist sqlite.org/lang_createtable.html - "SQL standardına göre, PRIMARY KEY her zaman NULL değil anlamına gelir. Ne yazık ki, bazı erken sürümlerde bir hata nedeniyle, bu SQLite için durum böyle değildir. [...] NULL değerler, diğer NULL'ler de dahil olmak üzere diğer tüm değerlerden farklı kabul edilir. "
İnanılmaz Ocak

Evet, SQL NULL'larında her zaman yanlış karşılaştırılır. Bu nedenle, ilişkisel teori NULL'u herhangi bir anahtar bileşenin değeri olarak özellikle hariç tutar. Bununla birlikte, SQLite ilişkisel uygulamadır. Görünüşe göre yazarlar "eşit" olmayan çoklu anahtarlara pragmatik olarak izin vermeyi seçtiler. Açıkçası NULL değerlerine anahtar değer olarak izin verilmemesi tercih edilir.
holdenweb

31

Temel:

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

Sütunlarınız diğer tabloların yabancı anahtarlarıysa (genel durum):

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

Birincil anahtar alanları null değil olarak bildirilmelidir (birincil anahtarın tanımı benzersiz olması ve null olmaması gerektiğinden standart değildir). Ancak aşağıda, herhangi bir DBMS'deki tüm çok sütunlu birincil anahtarlar için iyi bir uygulamadır.

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

11

SQLite 3.8.2 sürümünden beri, açık NOT NULL belirtimlerine bir alternatif "WITH ROWID" belirtimi: [ 1 ]

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

"ROWID OLMADAN" tablolar potansiyel verimlilik avantajlarına sahiptir, bu nedenle dikkate alınması gereken daha az ayrıntılı bir alternatif:

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

Örneğin, sqlite3 komut isteminde: sqlite> insert into t values(1,null,3); Error: NOT NULL constraint failed: t.c2


Bugünlerde bunu okuyan herkes için WITHOUT ROWIDek etkileri vardır ve NOT NULLbirincil anahtarınızın yanında yazmaya alternatif olarak kullanılmamalıdır .
shadowtalker


2

PRIMARY KEY (id, name)benim için çalışmadı. Bunun yerine bir kısıtlama eklemek işi yaptı.

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


1

Aşağıdaki kod, SQLite içinde birincil anahtar olarak 2 sütunlu bir tablo oluşturur .

ÇÖZÜM:

CREATE TABLE IF NOT EXISTS users (id TEXT NOT NULL, name TEXT NOT NULL, pet_name TEXT, PRIMARY KEY (id, name))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.