2009-12-10 26 views
19

Tôi có bảng người dùng MySQL có khóa chính là khóa chính là số nguyên tự động gia tăng. Bảng đã được điền với các bản ghi có khóa nằm trong khoảng từ 0 đến 30.000. Tuy nhiên, không phải tất cả hồ sơ đều có. Một số người dùng đã bị xóa và do đó tôi có "lỗ hổng".Làm cách nào để ghi đè thuộc tính của khóa chính tăng tự động khi chèn giá trị vào bảng MySQL?

Giờ đây, khách hàng đã nhận ra họ đã xóa nhầm một nhóm người dùng và họ muốn tôi cấp lại những người dùng đó giữ cùng một ID mà họ có, để tương thích với back-end của thương mại điện tử. một máy hoàn toàn khác, nhưng sử dụng cùng một ID cho khách hàng.

Tại thời điểm này tôi:

  1. thay đổi cấu trúc của bảng, bằng cách loại bỏ các tài sản auto_increment từ ID
  2. thêm các hồ sơ tôi cần, xác định ID của họ
  3. quay trở lại các thay đổi để cấu trúc của bảng.

Có cách nào tốt hơn để đạt được điều này không? Có hàm SQL override nào cho phép tôi buộc MySQL chấp nhận một giá trị duy nhất nhưng không nhất thiết phải là "số tiếp theo trong dòng" không?

+0

Không phải là câu trả lời cho vấn đề ở đây, nhưng lưu ý quan trọng: Để tránh vô tình xóa bản ghi, không bao giờ thực sự xóa bản ghi. Đặt một trường như 'isActive' hoặc' deleted' hoặc 'archived' hoặc một cái gì đó của tự nhiên thành false (hoặc true, tùy theo ý nghĩa nào). Và khi bạn kéo các bản ghi, chỉ kéo các bản ghi được đánh dấu là đang hoạt động. Bằng cách đó những sai lầm như thế này trở nên dễ dàng để sửa chữa. Và đó là một hệ thống mạnh mẽ và linh hoạt hơn. (Lưu ý không quan trọng: Tôi đến đây để tìm cách tôi có thể tự động tăng lên như 1000 và chèn các bản ghi quan trọng vào nơi tôi muốn.) – RoboticRenaissance

Trả lời

17

Bạn không phải tắt tính năng auto_increment. Khi bạn chèn một hàng vào bảng và bạn chỉ định giá trị khóa chính trong hàng, id bạn muốn được lưu trữ trong cơ sở dữ liệu. auto_increment chỉ được sử dụng, khi bạn bỏ qua trường khóa chính.

EDIT: Tôi nghĩ tôi có thể đưa ra ví dụ cho điều đó:

mysql> describe test; 
+-------+------------------+------+-----+---------+----------------+ 
| Field | Type    | Null | Key | Default | Extra   | 
+-------+------------------+------+-----+---------+----------------+ 
| id | int(10) unsigned | NO | PRI | NULL | auto_increment | 
| value | varchar(45)  | NO |  | NULL |    | 
+-------+------------------+------+-----+---------+----------------+ 
2 rows in set (0.02 sec) 

mysql> insert into test (value) values ('row 1'); 
Query OK, 1 row affected (0.06 sec) 

mysql> select * from test; 
+----+-------+ 
| id | value | 
+----+-------+ 
| 1 | row 1 | 
+----+-------+ 
1 row in set (0.00 sec) 

mysql> insert into test values (15, 'row 2'); 
Query OK, 1 row affected (0.03 sec) 

mysql> select * from test; 
+----+-------+ 
| id | value | 
+----+-------+ 
| 1 | row 1 | 
| 15 | row 2 | 
+----+-------+ 
2 rows in set (0.00 sec) 

EDIT 2

mysql> insert into test (id, value) values (3, 'row 3'); 
Query OK, 1 row affected (0.00 sec) 

mysql> select * from test; 
+----+-------+ 
| id | value | 
+----+-------+ 
| 1 | row 1 | 
| 15 | row 2 | 
| 3 | row 3 | 
+----+-------+ 
3 rows in set (0.00 sec) 
+7

Chỉ nhận ra rằng điều này chỉ hoạt động khi bạn đặt "id" thủ công so với "id" lớn nhất đã có trong bảng. Phương thức không thành công nếu bạn cố gán một "id" không tồn tại trong bảng nhưng thấp hơn giá trị lớn nhất đã chèn ...: -/ – mac

+2

@mac - Điều này cũng hoạt động với các id thấp hơn. Xem các thay đổi của tôi ở trên –

+0

Cảm ơn bạn đã quay lại với tôi. Tôi đã kiểm tra bằng cách làm theo "hướng dẫn" của bạn và tôi có thể quản lý. Tôi sẽ thử nghiệm trên DB ban đầu mà tôi đã thất bại và sẽ báo cáo lại. Có thể mất vài ngày. – mac

1

Để tránh vấn đề với việc thực hiện AUTO_INCREMENT (hoặc các lĩnh vực nhận dạng trong bất kỳ cơ sở dữ liệu), Tôi không bao giờ sử dụng nó khi một cái gì đó bên ngoài cơ sở dữ liệu (hoặc một người hoặc một hệ thống) phải biết về các giá trị.

Các MySQL documentation nói:

Thuộc tính AUTO_INCREMENT có thể sử dụng để tạo ra một bản sắc độc đáo cho hàng mới.

Theo tôi, đó là tất cả những gì bạn cần quan tâm. Các con số ở đó và chúng là duy nhất. Không bao giờ nhớ những gì họ đang có và nếu họ có "khoảng trống" hoặc "lỗ". Nếu bạn muốn ID hiển thị bên ngoài, có thể một số loại GUID sẽ tốt hơn.

+1

Đây không phải là câu trả lời thực sự ... nhưng cảm ơn bạn về mẹo! (1) Về mặt triết học, tôi đồng ý với bạn và sẽ sử dụng "mẫu bộ điều hợp" để làm những gì bạn đề xuất. Lịch sử của các di sản của dự án cụ thể này tuy nhiên đã loại trừ tùy chọn đó. – mac

+0

Điều đó dễ hiểu. Bàn tay của tôi thường bị trói khi làm việc trên các hệ thống cũ. Hy vọng rằng những người khác sẽ thấy điều này và tiết kiệm cho mình một nhức đầu nhỏ. –

1

Tôi gặp sự cố tương tự. Tôi phát hiện ra rằng bạn có thể đặt ID thành bất kỳ số nào trong bản cập nhật, mặc dù bạn không thể đặt ID đó dưới mức tối thiểu hiện tại trong một lần chèn.Để giải quyết vấn đề này, tôi đã viết một tập lệnh đã chuyển đổi dữ liệu nhập của tôi thành một chuỗi các câu lệnh SQL, với một cặp giống như sau cho mỗi hàng dữ liệu:

// This inserts the record with the next auto_increment id<br /> 
INSERT INTO mytable (ID, NAME, OTHER_COL...) VALUES (17, 'UNIQUE VALUE', 'other value'...);<br /> 
// This sets the correct ID on the newly inserted record<br /> 
UPDATE mytable SET ID=17 WHERE NAME='UNIQUE VALUE'; 

Nếu bạn không có một trường duy nhất, sau đó bạn có thể viết một câu lệnh SQL để lấy ID lớn nhất và cập nhật ID đó cho đúng ID trước khi chèn bản ghi tiếp theo. Tôi hi vọng cái này giúp được!

0

Có thể, trình điều khiển bạn sử dụng đọc lược đồ bảng và điều chỉnh cho nó. Khi nó thấy cột auto_increment, nó bỏ qua giá trị của nó. Đây là trường hợp của C# DataAdapter, như trong Generating insert statement that includes identity column.

Khi họ nói DataAdapter không thể được định cấu hình và tùy chọn duy nhất là sử dụng lệnh thủ công insert.

Các vấn đề liên quan