5

Trong ứng dụng Rails hiện tại của tôi, tôi đang giải quyết xung đột lịch biểu bằng cách sắp xếp các mô hình theo trường "created_at". Tuy nhiên, tôi nhận ra rằng khi chèn nhiều mô hình từ một biểu mẫu cho phép điều này, tất cả các lần created_at đều giống nhau!Có thể dựa vào khóa chính tăng tự động trong cơ sở dữ liệu của bạn không?

Đây là câu hỏi về thực hành lập trình tốt nhất: Ứng dụng của bạn có thể dựa vào cột ID trong cơ sở dữ liệu của bạn để tăng dần và lớn hơn với mỗi INSERT để có được thứ tự sáng tạo không? Nói cách khác, tôi có thể sắp xếp một nhóm các hàng tôi kéo ra khỏi cơ sở dữ liệu của tôi bằng cột ID của họ và được đảm bảo đây là một loại chính xác dựa trên thứ tự sáng tạo? Và đây có phải là một thực hành tốt trong ứng dụng của tôi không?

Trả lời

1

Điều đó tùy thuộc vào nhà cung cấp cơ sở dữ liệu của bạn.

MySQL Tôi tin rằng các phím tăng tự động hoàn toàn đơn đặt hàng. SQL Server Tôi không biết chắc chắn rằng nó có hay không nhưng tôi tin rằng nó.

Nơi bạn gặp phải sự cố là với cơ sở dữ liệu không hỗ trợ chức năng này, đáng chú ý nhất là Oracle sử dụng chuỗi, gần như không được đặt hàng hoàn toàn.

Một giải pháp thay thế có thể là dành thời gian đã tạo và sau đó là ID.

+0

Tôi thích ý tưởng về dự phòng, sắp xếp theo một và sau đó sử dụng ID cho loại thứ cấp. . . cảm ơn! – BushyMark

+0

Trình tự Oracle được sắp xếp cho các bản cài đặt không phải RAC, phần lớn trong số đó. –

2

Số nhận dạng được tạo sẽ là duy nhất. Bất kể bạn sử dụng Trình tự, như trong PostgreSQL và Oracle hay nếu bạn sử dụng một cơ chế khác như tự động tăng MySQL.

Tuy nhiên, Chuỗi thường được mua nhiều nhất trong số hàng loạt, ví dụ 20 số. Vì vậy, với PostgreSQL bạn không thể xác định trường nào được chèn trước. Thậm chí có thể có khoảng trống trong id của hồ sơ được chèn vào.

Vì vậy, bạn không nên sử dụng trường id được tạo cho một tác vụ như vậy để không dựa vào chi tiết triển khai cơ sở dữ liệu.

Tạo một trường hợp tạo hoặc Cập nhật khi thực hiện lệnh tốt hơn nhiều để sắp xếp theo thời gian tạo hoặc cập nhật sau này. Ví dụ:

INSERT INTO A (data, created) VALUES (smething, DATE()) 
UPDATE A SET data=something, updated=DATE() 
0

Tôi tin rằng câu trả lời cho câu hỏi của bạn là có ... nếu tôi đọc giữa các dòng, tôi nghĩ rằng bạn lo ngại rằng hệ thống có thể sử dụng lại số ID của được 'mất tích' trong trình tự, và do đó nếu bạn đã sử dụng 1,2,3,5,6,7 làm số ID, trong tất cả các triển khai tôi biết, số ID tiếp theo sẽ luôn là 8 (hoặc có thể cao hơn), nhưng tôi không ' t biết bất kỳ DB nào sẽ cố gắng và tìm ra bản ghi Id # 4 bị thiếu, vì vậy hãy cố gắng sử dụng lại số ID đó.

Mặc dù tôi quen thuộc nhất với SQL Server, tôi không biết tại sao bất kỳ nhà cung cấp nào cố gắng lấp đầy khoảng trống trong chuỗi - hãy nghĩ đến chi phí giữ danh sách ID không sử dụng, trái ngược với việc luôn theo dõi của số I cuối cùng được sử dụng và thêm 1.

Tôi muốn bạn có thể yên tâm dựa vào số ID được chỉ định tiếp theo luôn cao hơn số cuối cùng - không chỉ duy nhất.

0

Có id sẽ là duy nhất và không, bạn không thể và không nên dựa vào nó để sắp xếp - nó có đó để đảm bảo tính duy nhất của hàng. Cách tiếp cận tốt nhất là, như emktas đã chỉ ra, để sử dụng một trường "được cập nhật" hoặc "được tạo" riêng biệt chỉ cho thông tin này.

Đối với thiết lập thời gian sáng tạo, bạn chỉ có thể sử dụng một giá trị mặc định như thế này

CREATE TABLE foo (
    id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL; 
    created TIMESTAMP NOT NULL DEFAULT NOW(); 
    updated TIMESTAMP; 
    PRIMARY KEY(id); 
) engine=InnoDB; ## whatever :P 

Bây giờ, mà sẽ chăm sóc thời gian sáng tạo. với thời gian cập nhật tôi sẽ đề nghị một UPDATE kích hoạt SAU như thế này (tất nhiên bạn có thể làm điều đó trong một truy vấn riêng biệt, nhưng cò, theo ý kiến ​​của tôi, là một giải pháp tốt hơn - minh bạch hơn):

DELIMITER $$ 
CREATE TRIGGER foo_a_upd AFTER UPDATE ON foo 
FOR EACH ROW BEGIN 
    SET NEW.updated = NOW(); 
END; 
$$ 
DELIMITER ; 

Và nên làm vậy.

EDIT: Khốn khổ là tôi. Foolishly tôi đã không chỉ định, rằng điều này là dành cho mysql, có thể có một số khác biệt trong các tên chức năng (cụ thể là, 'NOW') và bitty tinh tế bitty.

+1

Bạn đang bỏ qua những gì OP cho biết: anh ta đã có một trường created_at và nó giống nhau khi một số mục được chèn vào cùng một lúc, do đó câu hỏi của anh ta. – cletus

+0

Nó, thực sự, có vẻ như, mà tàu của tôi suy nghĩ, wildly swerving như nó có, đã lang thang ra một ca khúc bên. Lấy làm tiếc. Bạn đương nhiên là đúng. Sắp xếp đầu tiên bởi created_at và sau đó là id, có lẽ là giải pháp đơn giản nhất (mặc dù nó có thể không đảm bảo đúng thứ tự, nó chỉ đảm bảo rằng các hàng có cùng giá trị created_at sẽ được trả về theo thứ tự giống nhau thời gian). – shylent

0

Một báo trước cho câu trả lời của EJB:

SQL không đảm bảo đặt hàng nếu bạn không chỉ định thứ tự theo cột. Ví dụ. nếu bạn xóa một số hàng đầu, sau đó chèn chúng, những cái mới có thể kết thúc sống ở cùng một vị trí trong db những cái cũ đã làm (mặc dù với ID mới), và đó là những gì nó có thể sử dụng như sắp xếp mặc định của nó.

FWIW, tôi thường sử dụng thứ tự theo ID làm phiên bản hiệu quả của đơn đặt hàng bởi created_at. Nó rẻ hơn ở chỗ nó không yêu cầu thêm chỉ mục vào trường datetime (lớn hơn và do đó chậm hơn chỉ số khóa chính nguyên đơn giản), được bảo đảm khác nhau và tôi không thực sự quan tâm nếu một vài hàng thêm vào khoảng cùng một loại thời gian theo một thứ tự hơi khác.

0

Đây có lẽ là động cơ DB phụ thuộc. Tôi sẽ kiểm tra xem DB của bạn thực hiện các trình tự như thế nào và nếu không có vấn đề về tài liệu thì tôi sẽ quyết định dựa vào ID.

Ví dụ: Postgresql sequence là OK trừ khi bạn chơi với các tham số bộ nhớ cache trình tự.

Có khả năng lập trình viên khác sẽ tự tạo hoặc sao chép bản ghi từ DB khác với cột ID sai. Tuy nhiên tôi sẽ đơn giản hóa vấn đề. Đừng bận tâm với các trường hợp xác suất thấp, nơi ai đó sẽ tự hủy toàn vẹn dữ liệu. Bạn không thể bảo vệ chống lại mọi thứ.

Lời khuyên của tôi là dựa vào ID được tạo theo trình tự và di chuyển dự án của bạn về phía trước.

0

Về lý thuyết, số id cao nhất là số cuối cùng được tạo. Hãy nhớ rằng mặc dù các cơ sở dữ liệu đó có khả năng tạm thời tắt chèn của giá trị được tạo tự động, chèn một số bản ghi manaully và sau đó bật nó trở lại. Các chèn này thường không được sử dụng trên một hệ thống sản xuất nhưng đôi khi có thể xảy ra khi di chuyển một đoạn dữ liệu lớn từ một hệ thống khác.

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