Sqlite'de otomatik artış var mı?


109

Ben otomatik artan bir tablo oluşturmak çalışıyorum primary keyiçinde Sqlite3 . Bunun gerçekten mümkün olup olmadığından emin değilim, ancak sadece diğer alanları belirtmem gerektiğini umuyorum.

Örneğin:

CREATE TABLE people (id integer primary key auto increment, first_name varchar(20), last_name varchar(20));

Sonra, bir değer eklediğimde, yalnızca şunları yapmam gerektiğini umuyordum:

INSERT INTO people
VALUES ("John", "Smith");

Bu mümkün mü?

Windows 7 sqlite3altında çalışıyorum cygwin.

Yanıtlar:


167

ROWID adlı ücretsiz bir tane alırsınız. Bu, isteseniz de istemeseniz de her SQLite tablosunda bulunur.

INTEGER PRIMARY KEY türünde bir sütun eklerseniz, bu sütun otomatik ROWID sütununa işaret eder (bunun takma adıdır).

ROWID (ne isimle adlandırırsanız adlandırın), beklediğiniz gibi, bir satır EKLEDİĞİNİZDE bir değer atanır. INSERT üzerine açıkça NULL olmayan bir değer atarsanız, otomatik artış yerine belirtilen değeri alır. INSERT üzerine açıkça bir NULL değeri atarsanız, sonraki otomatik artış değerini alır.

Ayrıca şunlardan kaçınmaya çalışmalısınız:

 INSERT INTO people VALUES ("John", "Smith");

ve kullan

 INSERT INTO people (first_name, last_name) VALUES ("John", "Smith");

yerine. İlk sürüm çok kırılgandır - tablo tanımınıza sütunları eklerseniz, taşırsanız veya silerseniz, INSERT başarısız olur veya yanlış veriler üretir (değerler yanlış sütunlardadır).


53
ROWID, SAME değeri birden çok kez oluşturulabileceğinden gerçek bir otomatik artışla tam olarak aynı değildir. Örneğin, boş bir tablo ile 3 satır eklemek, beklendiği gibi 3. satıra 3 ROWID verir. Ancak 2 satır ekleyin, sonuncuyu silin ve başka bir tane ekleyin, eklenen 3. satıra 2. satırda olduğu gibi 2 satırlık bir ROWID verir. Bu nedenle, tablolar, silme işlemlerinin meydana geldiği ve silme işlemlerinin veya ROWID nulling işlemlerinin ilgili tablolarda yapılmadığı bir tablodaki ROWID'lere başvurursa bariz ciddi bir sorun vardır.
Nick

10
Cevaptan açık değilse, seçim ifadenizde ROWID kullanabilirsiniz örn.select rowid from people;
Colin D

@Nick sadece fikrinizi tamamlamak için: bu yüzden otomatik artış bir güvenlik önlemidir. Ve ROWID'de çarpışan iki satırdan bahsetmiyoruz.
YoussefDir

69

Evet, bu mümkün. Göre SQLite SSS :

Bildirilen bir sütun otomatik olarak INTEGER PRIMARY KEYartacaktır.


12
Uku'nun bahsettiği ve belgelerde de açıklandığı gibi uyarı, bunun çalışması için kimlik için bir NULL girmeniz gerektiğidir.
Matt Hulse

22
INSERT için sütun listesini dışarıda bırakırsanız yalnızca bir NULL kullanmanız gerekir - asla iyi bir uygulama değildir. Sütunları belirtirseniz, otomatik artış sütununu atlayabilirsiniz ve bir sonraki değeri alır.
Larry Lustig

5
Başka bir uyarı: "INTEGER ..." tam olarak yukarıda verildiği gibi yazın. Kısa bir "INT ..." çalışmayacaktır.
Marcin Wojnarski

27

Bugün itibariyle - Haziran 2018


İşte resmi SQLite belgelerinin konu hakkında söyledikleri (kalın ve italik benimdir):

  1. AUTOINCREMENT'e kelime yüklemektedir ekstra CPU, hafıza, disk alanı, ve disk I / O havai ve kesinlikle gerekli değilse kaçınılmalıdır. Genellikle gerekli değildir.

  2. SQLite'da, INTEGER PRIMARY KEY türündeki bir sütun , her zaman 64 bitlik işaretli tamsayı olan ROWID için bir takma addır (ROWID tabloları OLMADAN hariç).

  3. Bir INSERT'te, ROWID veya INTEGER PRIMARY KEY sütununa açıkça bir değer verilmemişse, bu durumda otomatik olarak kullanılmayan bir tamsayı, genellikle şu anda kullanımda olan en büyük ROWID'den bir fazla doldurulur . Bu, AUTOINCREMENT anahtar kelimesinin kullanılıp kullanılmadığına bakılmaksızın geçerlidir.

  4. Eğer AUTOINCREMENT'e anahtar kelime görünür INTEGER PRIMARY KEY sonra otomatik ROWID atama algoritmasını değiştirir, yeniden kullanımını önlemek veritabanının ömrü boyunca ROWIDs. Başka bir deyişle, OTOMATİK EKLEME'nin amacı, önceden silinmiş satırlardan ROWID'lerin yeniden kullanılmasını önlemektir.


11

Bunu okudun mu OTOMATİK EKLEME alanını nasıl oluşturabilirim?

INSERT INTO people
VALUES (NULL, "John", "Smith");

Yani demek istediğim, yapmaya çalıştığım şey mümkün değil, ama bir çeşit simülasyon yapabilirim. Ekte boş değer kullanmam gerekiyor mu?
ewok

1
hiçbir şey yapmanıza gerek yok ama id olarak her zaman NULL ekliyorsanız, bu sadece sqlite'ın bunu dahili olarak nasıl yaptığını açıklar.
Uku Loskit

7
INSERT üzerindeki NULL, yalnızca INSERT için sütunların listesini belirtmezseniz gereklidir (bu durumda, sütun sayısıyla tam olarak eşleşen bir dizi değere ihtiyacınız vardır ve yer tutucu olarak NULL kullanmanız gerekir). Ancak sütun listesini belirtmeden INSERT yapmak asla iyi bir uygulama değildir. Sütun listesini belirtirseniz, hem otomatik artış sütununu hem de NULL değerini dışarıda bırakın, beklediğiniz sonucu alırsınız.
Larry Lustig

4

AUTOINCREMENTYakın anahtar kelime belirtilmemelidir PRIMARY KEY. Otomatik artışlı birincil anahtar oluşturma ve ekleme örneği:

$ sqlite3 ex1

CREATE TABLE IF NOT EXISTS room(room_id INTEGER PRIMARY KEY, name VARCHAR(25) NOT NULL, home_id VARCHAR(25) NOT NULL);

INSERT INTO room(name, home_id) VALUES ('test', 'home id test');

INSERT INTO room(name, home_id) VALUES ('test 2', 'home id test 2');

SELECT * FROM room;

verecek:

1|test|home id test
2|test 2|home id test 2

4

Rowid'in yanında, kendi otomatik artış alanınızı tanımlayabilirsiniz, ancak bu önerilmez. Otomatik olarak artan rowid kullandığımızda her zaman daha iyi bir çözüm olur.

AUTOINCREMENTAnahtar kelime yüklemektedir ekstra CPU, hafıza, disk alanı, ve disk I / O havai ve kesinlikle gerekli değilse kaçınılmalıdır. Genellikle gerekli değildir.

Ayrıntılı bilgi için burayı okuyun .


Görünüşe göre rowid her zaman otomatik olarak artmaz, Nick
rogerdpack

1
Doğru değil. Otomatik artış, birçok sistem için oldukça önemli bir gereklilik olan kimlikleri yeniden kullanmayacağı için bazı açılardan daha iyidir.
O'Rooney

4

SQLite AUTOINCREMENT, tablodaki bir alanın değerini otomatik olarak artırmak için kullanılan bir anahtar kelimedir. Otomatik olarak artırmak için belirli sütun adına sahip bir tablo oluştururken AUTOINCREMENT anahtar sözcüğünü kullanarak bir alan değerini otomatik olarak artırabiliriz.

AUTOINCREMENT anahtar sözcüğü yalnızca INTEGER alanıyla kullanılabilir. Sözdizimi:

AUTOINCREMENT anahtar kelimesinin temel kullanımı aşağıdaki gibidir:

CREATE TABLE table_name(
   column1 INTEGER AUTOINCREMENT,
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
);

Örnek için Aşağıya Bakın: ŞİRKET tablosunun aşağıdaki gibi oluşturulacağını düşünün:

sqlite> CREATE TABLE TB_COMPANY_INFO(
   ID INTEGER PRIMARY KEY   AUTOINCREMENT,
   NAME           TEXT      NOT NULL,
   AGE            INT       NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

Şimdi, aşağıdaki kayıtları TB_COMPANY_INFO tablosuna ekleyin:

INSERT INTO TB_COMPANY_INFO (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'MANOJ KUMAR', 40, 'Meerut,UP,INDIA', 200000.00 );

Şimdi kaydı seçin

SELECT *FROM TB_COMPANY_INFO
ID      NAME            AGE     ADDRESS             SALARY
1       Manoj Kumar     40      Meerut,UP,INDIA     200000.00

2

Bu cevabın biraz geç olduğunu biliyorum.
Bu cevabın amacı, şu anda veya gelecekte SQLite ile bu tür bir zorlukla karşılaşmaları ve bununla zor zamanlar geçirmeleri durumunda herkesin referansıdır.

Şimdi, sorgunuza dönüp baktığımızda, bunun gibi bir şey olmalı.

CREATE TABLE people (id integer primary key autoincrement, first_name varchar(20), last_name varchar(20));

Benim tarafımda çalışıyor. Bunun gibi

görüntü açıklamasını buraya girin

Sadece SQLite ile çalışıyorsanız, SQLite için DB Browser'a göz atmanızı öneririm . Farklı platformlarda da çalışır.


0

Yaptığınız şey doğrudur, ancak "otomatik artış" için doğru sözdizimi boşluksuz olmalıdır:

CREATE TABLE people (id integer primary key autoincrement, first_name string, last_name string);

(Ayrıca varchars'ınızı dizelere dönüştürdüğümü de unutmayın. Bunun nedeni SQLite'ın dahili olarak bir varchar'ı dizeye dönüştürmesi, öyleyse neden zahmet edesiniz?)

daha sonra eklentiniz mümkün olduğunca standart olarak SQL dilinde olmalıdır:

INSERT INTO people(id, first_name, last_name) VALUES (null, 'john', 'doe');

Kimliği atlarsanız, otomatik olarak artırılıp atanacağı doğru olsa da, kişisel olarak gelecekte değişebilecek otomatik mekanizmalara güvenmemeyi tercih ederim.

Otomatik artırma hakkında bir not: Birçok kişinin de belirttiği gibi SQLite çalışanları tarafından önerilmese de, otomatik artırma kullanılmıyorsa silinen kayıtların kimliklerinin otomatik olarak yeniden kullanılmasını sevmiyorum. Başka bir deyişle, silinmiş bir kaydın kimliğinin bir daha asla ve asla görünmemesini seviyorum .

HTH


Bu açıdan O'Rooney'in söylediklerini tamamen paylaşıyorum.
Luca Nanetti
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.