Có tăng tự động trong sqlite không?


109

Tôi đang cố gắng tạo một bảng với số tự động tăng dần primary keytrong Sqlite3 . Tôi không chắc liệu điều này có thực sự khả thi hay không, nhưng tôi hy vọng chỉ phải chỉ định các trường khác.

Ví dụ:

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

Sau đó, khi tôi thêm một giá trị, tôi hy vọng chỉ phải làm:

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

Điều này thậm chí có thể?

Tôi đang chạy sqlite3dưới cygwintrong Windows 7.

Câu trả lời:


166

Bạn nhận được một miễn phí, gọi là ROWID. Điều này có trong mọi bảng SQLite cho dù bạn có yêu cầu hay không.

Nếu bạn bao gồm một cột loại INTEGER PRIMARY KEY, cột đó trỏ đến (là bí danh của) cột ROWID tự động.

ROWID (bằng bất kỳ tên nào bạn gọi) được gán một giá trị bất cứ khi nào bạn CHÈN một hàng, như bạn mong đợi. Nếu bạn chỉ định rõ ràng một giá trị không phải NULL trên INSERT, nó sẽ nhận giá trị đã chỉ định đó thay vì tự động tăng. Nếu bạn chỉ định một cách rõ ràng giá trị NULL trên INSERT, nó sẽ nhận được giá trị tự động tăng tiếp theo.

Ngoài ra, bạn nên cố gắng tránh:

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

Và sử dụng

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

thay thế. Phiên bản đầu tiên rất mỏng manh - nếu bạn thêm, di chuyển hoặc xóa các cột trong định nghĩa bảng của mình, INSERT sẽ bị lỗi hoặc tạo ra dữ liệu không chính xác (với các giá trị trong các cột sai).


53
ROWID không hoàn toàn giống với một tự động tăng thực sự vì giá trị SAME có thể được tạo nhiều lần. Ví dụ: với một bảng trống, việc chèn 3 hàng sẽ cung cấp cho hàng thứ 3 ROWID là 3 như mong đợi. Tuy nhiên, hãy chèn 2 hàng, xóa hàng cuối cùng và chèn một hàng khác, cung cấp cho hàng được chèn thứ 3 có ROWID là 2, giống như hàng thứ 2 đã có. Do đó, có một vấn đề nghiêm trọng rõ ràng nếu các bảng tham chiếu ROWIDs trong một bảng nơi xảy ra xóa và nơi xóa hoặc vô hiệu ROWID cũng không được thực hiện trong các bảng liên quan.
Nick

10
Trong trường hợp câu trả lời không rõ ràng, bạn có thể sử dụng ROWID trong câu lệnh đã chọn của mình, ví dụselect rowid from people;
Colin D

@Nick chỉ để bổ sung ý tưởng của bạn: vì vậy tự động tăng là một biện pháp an toàn. Và chúng tôi không nói về hai hàng va chạm trong ROWID.
YoussefDir

68

Có, điều này là có thể. Theo Câu hỏi thường gặp về SQLite :

Một cột được khai báo INTEGER PRIMARY KEYsẽ tự động tăng thêm.


12
Cảnh báo trước, như được đề cập bởi Uku, và cũng được giải thích trong tài liệu, là bạn cần chuyển NULL cho ID để điều này hoạt động.
Matt Hulse

22
Bạn chỉ cần sử dụng NULL nếu bạn bỏ qua danh sách các cột để CHÈN - không bao giờ là một phương pháp hay. Nếu bạn chỉ định các cột, bạn có thể chỉ cần bỏ đi cột tăng tự động và nó sẽ nhận được giá trị tiếp theo.
Larry Lustig

5
Một lưu ý khác: viết "INTEGER ..." chính xác như đã cho ở trên. Viết tắt "INT ..." sẽ KHÔNG hoạt động.
Marcin Wojnarski

26

Tính đến hôm nay - tháng 6 năm 2018


Đây là tài liệu SQLite chính thức nói về chủ đề này (chữ in đậm & nghiêng là của tôi):

  1. Các autoincrement áp đặt từ khóa thêm CPU, bộ nhớ, dung lượng đĩa, và đĩa I / O trên không và nên tránh nếu không cần thiết nghiêm ngặt. Nó thường không cần thiết.

  2. Trong SQLite, cột có kiểu INTEGER PRIMARY KEY là bí danh cho ROWID (ngoại trừ trong bảng KHÔNG ROWID) , cột này luôn là số nguyên có dấu 64 bit.

  3. Trên INSERT, nếu cột ROWID hoặc INTEGER PRIMARY KEY không được cung cấp rõ ràng một giá trị, thì cột này sẽ được điền tự động bằng một số nguyên không sử dụng, thường là một giá trị lớn hơn ROWID lớn nhất hiện đang được sử dụng. Điều này đúng bất kể có sử dụng từ khóa AUTOINCREMENT hay không.

  4. Nếu từ khóa AUTOINCREMENT xuất hiện sau INTEGER PRIMARY KEY , điều đó sẽ thay đổi thuật toán chỉ định ROWID tự động để ngăn việc sử dụng lại ROWID trong thời gian tồn tại của cơ sở dữ liệu. Nói cách khác, mục đích của AUTOINCREMENT là ngăn việc sử dụng lại ROWID từ các hàng đã xóa trước đó.


11

Bạn đã đọc chưa? Làm cách nào để tạo trường AUTOINCREMENT.

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

Vì vậy, những gì bạn đang nói là những gì tôi đang cố gắng làm là không thể, nhưng tôi có thể mô phỏng. Tôi cần sử dụng giá trị null trong chèn?
ewok

1
bạn không cần làm bất cứ điều gì ngoài việc luôn chèn NULL làm id, nó chỉ giải thích cách sqlite thực hiện nó trong nội bộ.
Uku Loskit

7
NULL trên INSERT chỉ được yêu cầu nếu bạn không chỉ định danh sách cột để CHÈN (trong trường hợp đó, bạn cần một số giá trị khớp chính xác với số cột và phải sử dụng NULL làm trình giữ chỗ). Nhưng thực hiện INSERT mà không chỉ định danh sách các cột không bao giờ là một phương pháp hay. Nếu bạn chỉ định danh sách các cột, chỉ cần bỏ đi cả cột tự động tăng và giá trị NULL, và bạn sẽ nhận được kết quả như mong đợi.
Larry Lustig

4

Không nên chỉ định AUTOINCREMENTtừ khóa gần PRIMARY KEY. Ví dụ về cách tạo khóa chính tự động tăng và chèn:

$ 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;

sẽ cho:

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

4

Bên cạnh rowid, bạn có thể xác định trường tăng tự động của riêng mình nhưng nó không được khuyến khích. Nó luôn là giải pháp tốt hơn khi chúng ta sử dụng rowid được tăng tự động.

Các AUTOINCREMENTáp đặt từ khóa thêm CPU, bộ nhớ, dung lượng đĩa, và đĩa I / O trên cao và nên tránh nếu không cần thiết nghiêm ngặt. Nó thường không cần thiết.

Đọc ở đây để biết thông tin chi tiết.


rõ ràng rowid không phải luôn luôn tự động tăng lên, xem bình luận của Nick
rogerdpack

1
Không đúng. Tự động gia tăng ở một số khía cạnh tốt hơn, vì nó sẽ không sử dụng lại ID - một yêu cầu khá quan trọng đối với nhiều hệ thống.
O'Rooney

3

SQLite AUTOINCREMENT là một từ khóa được sử dụng để tự động tăng giá trị của một trường trong bảng. Chúng tôi có thể tự động tăng giá trị trường bằng cách sử dụng từ khóa AUTOINCREMENT khi tạo bảng với tên cột cụ thể để tự động tăng giá trị đó.

Từ khóa AUTOINCREMENT chỉ có thể được sử dụng với trường INTEGER. Cú pháp:

Cách sử dụng cơ bản của từ khóa AUTOINCREMENT như sau:

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

Ví dụ Xem bên dưới: Hãy xem xét bảng COMPANY sẽ được tạo như sau:

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

Bây giờ, hãy chèn các bản ghi sau vào bảng TB_COMPANY_INFO:

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

Bây giờ Chọn bản ghi

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

2

Tôi biết câu trả lời này hơi muộn.
Mục đích của tôi cho câu trả lời này là để mọi người tham khảo nếu họ gặp phải loại thử thách này với SQLite ngay bây giờ hoặc trong tương lai và họ đang gặp khó khăn với nó.

Bây giờ, nhìn lại truy vấn của bạn, nó sẽ giống như thế này.

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

Nó hoạt động trên đầu của tôi. Như vậy,

nhập mô tả hình ảnh ở đây

Chỉ trong trường hợp bạn đang làm việc với SQLite, tôi khuyên bạn nên kiểm tra Trình duyệt DB cho SQLite . Hoạt động trên các nền tảng khác nhau.


0

Những gì bạn làm là đúng, nhưng cú pháp chính xác cho 'tự động tăng' không được có khoảng trắng:

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

(Cũng xin lưu ý rằng tôi đã thay đổi varchars của bạn thành chuỗi. Đó là bởi vì SQLite chuyển nội bộ varchar thành một chuỗi, vậy tại sao phải bận tâm?)

thì phần chèn của bạn phải bằng ngôn ngữ SQL càng chuẩn càng tốt:

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

trong khi đúng là nếu bạn bỏ qua id, nó sẽ tự động tăng và được gán, cá nhân tôi không muốn dựa vào các cơ chế tự động có thể thay đổi trong tương lai.

Một lưu ý về tính năng tự động gia tăng: mặc dù, như nhiều người đã chỉ ra, nó không được khuyến khích bởi những người sử dụng SQLite, tôi không thích việc tự động sử dụng lại id của các bản ghi đã xóa nếu tính năng tự động gia tăng không được sử dụng. Nói cách khác, tôi thích rằng id của một bản ghi đã bị xóa sẽ không bao giờ xuất hiện nữa.

HTH


Về mặt này, tôi hoàn toàn chia sẻ những gì O'Rooney nói.
Luca Nanetti
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.