Cách lưu trữ các trạng thái bản ghi (như đang chờ xử lý, hoàn tất, bản nháp, đã hủy)


17

Khá nhiều ứng dụng yêu cầu các bản ghi trong bảng của chúng phải có trạng thái, chẳng hạn như 'hoàn thành', 'bản nháp', 'bị hủy'. Cách tốt nhất để lưu trữ những trạng thái này là gì? Để minh họa những gì tôi nhận được ở đây là một ví dụ * rất ngắn).

Tôi có một ứng dụng Blog đơn giản và mỗi bài đăng có một trạng thái: được xuất bản, dự thảo hoặc đang chờ xử lý.

Cách tôi nhìn thấy nó có 2 cách để mô hình hóa điều này trong cơ sở dữ liệu.

  1. Bảng bài viết có một trường văn bản bao gồm văn bản trạng thái.
  2. Bảng Post có trường trạng thái chứa ID của bản ghi trong bảng PostStatus

Ví dụ Blog ở đây là một ví dụ rất đơn giản. Trường hợp một enum (nếu được hỗ trợ) có thể đủ. Tuy nhiên, tôi muốn trả lời câu hỏi để xem xét rằng danh sách các trạng thái có thể thay đổi bất cứ lúc nào, vì vậy có thể thêm hoặc xóa nhiều hơn.

Bất cứ ai có thể giải thích những lợi thế / bất lợi của từng?

Chúc mừng!

Lựa chọn ban đầu của tôi về điều này là tốt hơn là sử dụng một bảng khác và tìm trạng thái vì nó tốt hơn cho việc chuẩn hóa và tôi luôn được dạy rằng chuẩn hóa là tốt cho cơ sở dữ liệu


1
gbn

Bạn có ý nghĩa gì bởi "bất cứ lúc nào"? Điều đó có nghĩa là một phần của hoạt động người dùng hay là một phần của chu trình phát hành phần mềm?
kevin cline

Cả hai, trong trường hợp là bất kỳ phương pháp tiếp cận nào được đề cập ở đây được sử dụng tốt nhất. Vì vậy, nếu người dùng có thể thêm trạng thái mới hoặc nếu trạng thái mới được thêm vào một thời điểm sau trong dự án
veganista

Lưu trữ văn bản trong cơ sở dữ liệu có thể là một sự không chuẩn hóa tốt. Tôi nghĩ rằng nó có thể phụ thuộc vào chi tiết chính xác, ví dụ như mức độ thường xuyên tổ chức của bạn thay đổi quy trình của mình (dẫn đến thay đổi trạng thái có thể)?
Jaydee

Nếu người dùng có thể thêm trạng thái mới, thì đó hoàn toàn là một điều khác. Bạn có thể sẽ muốn ghi lại người dùng đang tạo, v.v. với trạng thái và chắc chắn sẽ cần một bảng khác.
kevin cline

Câu trả lời:


14

Lưu trữ trạng thái như một chỉ mục vào một bảng khác là một biến chứng không cần thiết. Lưu trữ trạng thái trực tiếp trong bảng theo cách dễ đọc. Trong mã ứng dụng sử dụng hằng số hoặc một kiểu liệt kê. Điều này sẽ dẫn đến mã ứng dụng đơn giản hơn và dễ dàng gỡ lỗi lớp dữ liệu.

Điều này không làm chuẩn hóa dữ liệu, nó chỉ thay đổi cách biểu diễn. Nếu cơ sở dữ liệu hỗ trợ liệt kê trực tiếp, sau đó sử dụng đó. Mặt khác, sử dụng một ràng buộc để hạn chế các giá trị cột. Bạn sẽ có một ràng buộc theo một trong hai cách: hoặc là một ràng buộc trực tiếp trên các giá trị cột hoặc ràng buộc khóa ngoài.

Có, bạn có thể phải trình bày trạng thái khác nhau cho những người dùng khác nhau. Đó là một vấn đề trình bày, được giải quyết trong lớp trình bày, không phải là lớp kiên trì.


1
+1, Chặn một nhu cầu cụ thể để giữ danh sách các trạng thái trong db, đây thường là cách đơn giản nhất, ít phức tạp nhất để thực hiện.
GrandmasterB

2
Điều này là ổn, trừ khi bạn bắt đầu thay đổi kiến ​​trúc trạng thái hoặc lưu trữ ngày đột biến
LastTribunal

10

Lưu trữ văn bản trạng thái là IMO không phải là một ý tưởng hay, vì ai đó có thể quyết định rằng "hoàn thành" nên được gọi là "hoàn thành" và sau đó bạn phải cập nhật cơ sở dữ liệu của mình, xem qua chương trình nếu ai đó mã hóa văn bản, v.v.

Những gì tôi đã thấy trong nhiều chương trình là mã số (1 = mới, 2 = dự thảo, 3 = xác thực, 4 = hoàn thành, 99 = bị hủy) hoặc mã chữ số ngắn ("MỚI", "DRA", "INV "," COM "," CÓ THỂ "). Cái sau làm cho mã (trong chương trình hoặc trong cơ sở dữ liệu) dễ đọc hơn với con người, nói chung là một điều tốt. Mặt khác, các mã số giúp dễ dàng thực hiện các phép so sánh "lớn hơn" hoặc "nhỏ hơn"

select * from myrecords where status < Status.Complete;

Một số kẻ ngốc cũng có thể làm khó ID.
Morons

Một lợi thế khác của ID là bạn cần cung cấp nội địa hóa. Bạn có thể sử dụng ID của mình để tra cứu chuỗi tài nguyên và hiển thị. Với chuỗi mã hóa cứng này là không thể
Armitage

3
Tôi không nghĩ làm các trạng thái bằng cách sử dụng các phép so sánh "lớn hơn" hoặc "nhỏ hơn" như bạn đã trình bày là một ý tưởng hay. Nó có thể hoạt động cho các ứng dụng đơn giản hơn như ví dụ này nhưng không tốt cho các ứng dụng phức tạp hơn (mặc dù tôi chắc chắn bạn biết điều đó)
veganista

1
@armitage: hoàn toàn có thể thực hiện tra cứu bằng chuỗi. Tên tài nguyên là các chuỗi:status.draft=Draught
kevin cline

veganista: Chắc chắn, có thể có những khó khăn lớn hơn / nhỏ hơn so với so sánh, nhưng tôi đã thấy các hệ thống lớn, phức tạp làm được điều đó và sống.
user281377

3

Ba quy tắc của cơ sở dữ liệu quan hệ:

  1. Bình thường hóa
  2. Bình thường hóa
  3. Bình thường hóa

Vì vậy, câu hỏi của bạn trả lời chính nó. Giữ trạng thái bên trong bảng của chính nó và sử dụng GUID / UUID làm id của bạn . GUIDS được lập chỉ mục rất nhanh và khắc phục các vấn đề nội tại để tăng số lượng. Với một id, bạn có thể thực hiện những điều thú vị như yêu cầu DB cho tất cả các bài đăng đã hoàn thành bằng cách sử dụng id và vì bạn đang làm việc trong mô hình db quan hệ, nên nó rất nhanh. Nếu bạn chỉ có một trường, DB phải lặp qua từng hàng đơn lẻ và thực hiện so sánh văn bản, có thể với munging, và điều đó rất chậm.

Tên trạng thái bài đăng có thể thay đổi, thông tin thêm về trạng thái bài đăng có thể đi vào bảng, mọi thứ chỉ hoạt động nếu bạn bình thường hóa .

Ví dụ: bạn có thể thêm các mức trạng thái dưới dạng thông tin bổ sung, điều này sẽ cho phép đề cập đến so sánh ammoQ. Nhưng họ không phụ thuộc vào khóa để định vị, cho phép sắp xếp lại mức độ trạng thái mà không làm tổn hại đến tính toàn vẹn của DB. Bạn cũng có thể chèn các cấp độ bổ sung, đây là một mẹo khá hay nếu bạn có cấp độ liên quan đến khóa tự động.


Những lý do bạn đã nêu ở đây chính xác là những lý do tôi đang sử dụng một bảng khác để lưu trữ các staus của tôi. Lý do chính tại sao tôi đã hỏi câu hỏi này là để xem liệu đôi khi nó tốt để sử dụng một trường văn bản đơn giản hơn.
veganista

@Liam Chỉ khi nó bình thường hóa xuống một trường văn bản. Đó là, nếu trường văn bản của bạn chỉ phụ thuộc vào khóa chính và bạn đang tìm kiếm mọi thứ dựa trên khóa chính , với trường văn bản đi kèm. DB quan hệ là về các mối quan hệ, bạn có một mối quan hệ ở đây, vì vậy nó cần được xác định. Một trong vài trường hợp ngoại lệ là nếu bạn đang xử lý dữ liệu bẩn từ nguồn bên ngoài và bạn không có thời gian để mô hình hóa nó hoàn toàn. Tránh điều này nếu có thể.
Spencer Rathbun

che giấu đôi mắt, thương tiếc những GUID sẽ không bao giờ quay trở lại
sq33G

Bạn nên viết "ba lý thuyết về cơ sở dữ liệu quan hệ". Lý thuyết không phải lúc nào cũng thực tế. Việc lưu trữ mã trạng thái trực tiếp trong hồ sơ liên quan đến nó sẽ hiệu quả hơn. Nếu bạn không cần phải tìm kiếm nó để sử dụng nó, việc xóa liên kết sang bảng khác sẽ tiết kiệm rất nhiều xử lý lãng phí.
Suncat2000

Bị hạ cấp vì thông tin sai về các loại cột so với quét toàn bộ bảng.
igorrs

2

Có, bạn nên đi với tùy chọn 2, có bảng PostStatus.

Ngoài tất cả những lợi thế được đề cập trong các câu trả lời khác.

Hãy nhớ rằng các trạng thái cần được thêm hoặc xóa, bạn có thể có cột "đã bật" trong bảng PostStatus, vì vậy nếu trạng thái được xóa, hãy đánh dấu cột "đã bật" là "N", theo cách đó bạn sẽ có thể thêm hoặc xóa trạng thái và các hồ sơ hiện có sẽ ở lại mà không có vấn đề.


1

Tôi muốn thêm vào các câu trả lời sâu sắc khác rằng để bình thường hóa hoàn toàn, một sự thay đổi trạng thái của một thực thể thực sự được mô hình hóa trong một thực thể riêng biệt, ví dụ như 'statusChange'.

Bạn cần tham gia thêm với thực thể StatusChange, nhưng bạn sẽ có khả năng thêm thông tin bổ sung, chẳng hạn như diễn viên thực hiện thay đổi, có thể nhận xét về lý do tại sao thay đổi xảy ra và ngày mà StatusChange được thực hiện và có thể ngay cả khi nó trở nên hiệu quả


0

Sử dụng văn bản cho trạng thái trong bảng ghi có lẽ không phải là một ý tưởng hay vì điều này có thể thay đổi và sẽ khó thực hiện bất kỳ kiểm tra tính toàn vẹn dữ liệu nào khi chèn / cập nhật. Nếu bạn đang sử dụng DBMS với kiểu dữ liệu enum, bạn có thể sử dụng thay thế này (hiệu suất có thể sẽ không bị ảnh hưởng ... tùy thuộc).

Nếu trạng thái của bạn cần bất kỳ siêu dữ liệu nào (mô tả, được tạo bởi, tên thân thiện, ...), bạn sẽ cần lưu trữ trạng thái trong một bảng riêng biệt và có khóa trạng thái trong bảng ghi của bạn (đảm bảo bạn sử dụng khóa ngoại). Id không nhất thiết phải là một số, chỉ là PK của bảng trạng thái. Ngoài ra, nếu các trạng thái nằm trong bảng riêng của chúng, bạn có thể chia sẻ chúng qua các loại bản ghi (bảng) nếu có. Tôi sẽ không lo lắng về các vấn đề hiệu suất với THAM GIA vào bảng trạng thái.

Dù bạn làm gì, hãy đảm bảo bạn tránh các trạng thái ma thuật (1 cho hoạt động, 2 cho xóa, ...). Điều này phụ thuộc vào tài liệu và truyền thống luôn có xu hướng bị lạc trên dòng thời gian đủ lớn. Nếu bạn đang sử dụng id số, hãy đảm bảo có một liên kết văn bản ở đâu đó trong db của bạn.


Nếu bạn không lo lắng về hiệu suất, có khả năng bạn đang hy sinh khả năng mở rộng. Máy tính không thể tránh các trạng thái ma thuật: 0 và 1 về bản chất là ma thuật.
Suncat2000

0

Phụ thuộc vào mục đích của thiết kế cơ sở dữ liệu.

Nếu bạn thiết kế cơ sở dữ liệu chỉ đơn giản là để hỗ trợ ứng dụng (tức là các đối tượng (mã) là chủ của tất cả) thì sử dụng phép liệt kê (hoặc phép liệt kê psuedo cho các lớp không hỗ trợ chúng) và lưu trữ tên của enum là một ý tưởng tốt bởi vì bạn vẫn kiểm soát các giá trị được phép thông qua enum và bạn cũng làm cho bảng dễ đọc hơn một chút khi bạn buộc phải xem dữ liệu thô (điều này thường không xảy ra nếu mã thực sự cai trị tất cả). Nhưng nếu liệt kê được gắn cờ. Sau đó, tôi thường lưu trữ giá trị enum (số nguyên).


-1

Trạng thái rất quan trọng, bất cứ khi nào bạn nhận được thông tin bài đăng, bạn sẽ cần có trạng thái hoặc bạn sẽ muốn lọc các bài đăng theo trạng thái. Nếu bạn có trạng thái trong một bảng khác, bạn sẽ cần phải tham gia để có được thông tin này và do đó hiệu suất bị tổn hại. Chắc chắn bạn nên có trạng thái trong cùng một bảng. Và đặt một chỉ số trên đó! Bạn vẫn có thể sử dụng số nguyên làm trạng thái hoặc có thể là trường enum.


-2

Giải pháp chính xác là sử dụng Cửa hàng sự kiện / Nguồn với CQRS hoặc blockchain. Vấn đề với việc nắm bắt các sự kiện trong RDB là RDB lưu trữ ảnh chụp nhanh của một sự kiện duy nhất theo thời gian và những thứ như "Trạng thái / Trạng thái" là chuỗi các đột biến phát triển theo thời gian


Nếu bạn sẽ xuống bình chọn bài viết của tôi, sau đó làm cho một trường hợp. Khác, bạn chỉ là một người
lem lem
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.