Tôi có cần ID trong cơ sở dữ liệu của mình nếu hồ sơ có thể được xác định trước ngày không?


17

Tôi đang viết ứng dụng đầu tiên cho Android và sẽ sử dụng cơ sở dữ liệu SQLite vì vậy sẽ cố gắng giới hạn kích thước càng nhiều càng tốt, nhưng tôi nghĩ rằng câu hỏi này áp dụng chung cho thiết kế cơ sở dữ liệu.

Tôi đang lên kế hoạch lưu trữ các hồ sơ sẽ có văn bản và ngày tạo. Ứng dụng này là một ứng dụng độc lập, tức là nó sẽ không liên kết với internet và chỉ có một người dùng sẽ cập nhật nó, vì vậy không có khả năng sẽ có nhiều hơn một mục nhập với một ngày nhất định.

Bảng của tôi vẫn cần một cột ID? Nếu vậy, những lợi thế của việc sử dụng ID làm định danh hồ sơ trái ngược với Ngày là gì?


SQLite sẽ luôn tạo một cột số nguyên cho rowid nếu bạn không chỉ định PK số nguyên. Vì vậy, đừng tin vào việc không có cột "ID" như một cách để tiết kiệm dung lượng.
Codism

Tôi sẽ thêm rằng trong Android, một số lớp cần các bảng để có cột _id hoạt động. Thêm thông tin tại câu trả lời SO này .
bigstones

5
Nếu bạn nhận được ngày từ chính điện thoại và người dùng di chuyển đến múi giờ sớm hơn (và điện thoại của anh ấy / cô ấy tự động cập nhật thời gian) thì có một khả năng nhỏ là bạn có thể nhận được cùng một dấu thời gian nhiều lần.
Eugene

Câu trả lời:


22

IMHO, sử dụng cột ngày làm khóa chính là tốt nhất nên tránh.

Tôi đã làm việc trên các hệ thống trong đó trường ngày được sử dụng làm khóa chính và viết các truy vấn để lấy lại các tập hợp con của dữ liệu là một trở ngại nếu bạn làm việc với các trường ngày.

Một số điểm khác bạn có thể muốn xem xét:

Bạn có thể nghĩ rằng một điểm trong thời gian là duy nhất, nhưng điều đó phụ thuộc vào mức độ chi tiết của cột ngày. Có phút, giây, mili giây vv Có thể bạn được hoàn toàn chắc chắn rằng bạn sẽ không bao giờ có được một sự vi phạm khóa chính?

Cuối cùng, nếu bạn muốn di chuyển cơ sở dữ liệu sang nền tảng khác, bạn có thể gặp lại các vấn đề trong đó mức độ chi tiết của dữ liệu ngày khác nhau giữa các nền tảng.

Bạn tất nhiên phải cân bằng lý tưởng với những gì bạn phải làm việc với. Nếu không gian thực sự là một mối quan tâm lớn, sử dụng cột ngày có thể là ít tệ hơn của hai tệ nạn. Đó là một quyết định thiết kế bạn sẽ phải đưa ra.

Biên tập:

Tôi nên chỉ ra rằng không có cách nào điều này chỉ ra rằng đó là một quyết định thiết kế kém . Chỉ là có thể có vấn đề với tính thực tiễn của RDBMS.


đã được một lúc kể từ khi tôi viết một truy vấn SQLite, nhưng không lọc theo ngày giống với lọc theo số nguyên, ngoài tuyên bố dài hơn về các giá trị ràng buộc?
DougM

Nó chỉ dài dòng hơn và trên một số RDBMS bạn gặp phải vấn đề đó trong đó phần tử ngày và tháng bị đảo ngược nếu DB được thiết lập ở định dạng Hoa Kỳ.
Robbie Dee

Cảm ơn, đây là tất cả các câu trả lời tốt, nhưng kinh nghiệm của bạn trong công việc chắc chắn đóng dấu thỏa thuận.
Nieszka

Như một phần tái bút cho điều này: Chỉ hôm nay tôi đã được trao một vấn đề hỗ trợ cho bảng kiểm toán ứng dụng khi chúng bị vi phạm khóa chính đối với số nhân viên và PK ngày / giờ truy cập do chênh lệch múi giờ giữa 2 thiết bị khách. ..
Robbie Dee

13

Không, bạn không thực sự cần một cột ID được xác định trong lược đồ của mình nếu bạn có thể đảm bảo rằng sẽ không bao giờ có ngày trùng lặp.

NHƯNG ...

... Điều đó nói rằng, bạn cũng có thể sử dụng nó. Một bí mật nhỏ ở đây là SQLite đã có một ID tăng tự động duy nhất cho mỗi bảng có tên ROWID. Nếu bạn khai báo một cột số nguyên tăng tự động trong bảng của bạn dưới dạng PK, SQLite sẽ không tạo cột mới - nó sẽ chỉ đơn giản là bí danh mà cột ROWID tồn tại trước đó.

Trong SQLite, mỗi hàng của mỗi bảng đều có ROWID số nguyên 64 bit. ROWID cho mỗi hàng là duy nhất trong số tất cả các hàng trong cùng một bảng.

Bạn có thể truy cập ROWID của bảng SQLite bằng một tên cột đặc biệt ROWID, ROWID hoặc OID. Ngoại trừ nếu bạn khai báo một cột bảng thông thường để sử dụng một trong những tên đặc biệt đó, thì việc sử dụng tên đó sẽ đề cập đến cột được khai báo không phải là ROWID nội bộ.

Nếu một bảng chứa một cột kiểu INTEGER PRIMARY KEY, thì cột đó sẽ trở thành bí danh cho ROWID. Sau đó, bạn có thể truy cập ROWID bằng bất kỳ bốn tên khác nhau, ba tên ban đầu được mô tả ở trên hoặc tên được đặt cho cột INTEGER PRIMARY KEY. Tất cả các tên này là bí danh cho nhau và hoạt động tốt như nhau trong bất kỳ bối cảnh nào.

http://www.sqlite.org/autoinc.html

Vì vậy, bạn sẽ không tiết kiệm bất kỳ dung lượng nào bằng cách không sử dụng cột ID vì bạn sẽ nhận được một khoảng trống trên mỗi bảng cho dù bạn có muốn hay không!


9

Sử dụng trường ID nếu bất kỳ điều nào sau đây là đúng:

  1. Không có khóa tự nhiên tồn tại (ngày sẽ không phải là duy nhất)
  2. Trường ngày sẽ thay đổi thường xuyên
  3. Ngày có thể không được biết tại thời điểm chèn.
  4. Một định danh nhiều màu vượt quá ba cột, điều này sẽ khiến các phép nối quá dài.

Đọc câu hỏi này: Có nguồn kinh điển nào hỗ trợ cho những người thay thế toàn bộ không?

Biên tập:

Vì theo tôi, dường như không có điều nào ở trên đúng, bạn không cần sử dụng và trường ID, nhưng bạn có thể sử dụng một trường nếu muốn.


1
Các cột ID +1 là một mùi mã lược đồ, chỉ ra rằng dữ liệu của bạn không thực sự phù hợp với mô hình quan hệ.
Ross Patterson

10
@RossPatterson Tôi không chắc lắm. Tôi có thể nghĩ về một số trường hợp không có khóa tự nhiên có thể tồn tại, nhưng dữ liệu vẫn có thể phù hợp với mô hình quan hệ. Chỉ một trường hợp trên đỉnh đầu của tôi: lưu trữ thông tin về người sống. Nhiều quốc gia ( không phải tất cả! ) Chỉ định số nhận dạng duy nhất cho mỗi công dân, nhưng điều đó không có nghĩa là sử dụng số nhận dạng đó là phù hợp hoặc thậm chí có thể (có thể không được biết tại thời điểm tạo hồ sơ, có thể không được chỉ định hoặc sử dụng có thể bị cấm, ví dụ như theo quy định hiện hành). Điều đó có nghĩa là dữ liệu không phù hợp với mô hình quan hệ? Tôi không nghĩ vậy.
CVn

Và có một thực tế buồn cười là nơi có số nhận dạng duy nhất như vậy, cảnh sát (v.v.) đôi khi sử dụng các bản sao cho ID giả của họ. Và khi nó không cố ý, lỗi văn thư sẽ đảm bảo trùng lặp.
user470365

4
Cho dù nó được xây dựng trong (a la Oracle) hoặc được thêm dưới dạng cột thực sự, chúng đều rất hữu ích. Là một người đã ở cả hai phía của hàng rào (DBA & nhà phát triển), việc khấu trừ một bảng có id mà bạn có thể đảm bảo sẽ dễ dàng hơn rất nhiều.
Robbie Dee

1
@RobbieDee Bạn nói đúng. Nó lạc đề.
Tulains Córdova

2

Hãy nhớ rằng bạn cũng có thể muốn thay đổi ý nghĩa của cột "hẹn hò" từ created_atđến updated_athoặc bất kỳ sự thay đổi khác dọc theo những dòng này, mà tôi tìm được trường hợp rất phổ biến.

Thêm cột id trong một số trường hợp sẽ giúp bạn linh hoạt hơn khi thiết kế của bạn thay đổi.


+1 thêm date_created và date_modified vào các bảng rất hữu ích để theo dõi khi các hàng được tạo và cập nhật. Đây là giá trị trọng lượng của nó bằng vàng khi điều tra các vấn đề cập nhật kho / kho dữ liệu.
Robbie Dee
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.