Thiết kế cơ sở dữ liệu để cập nhật các bản ghi tuần tự


7

Tôi đang làm việc để tạo ra một mô hình dữ liệu để lưu trữ dữ liệu liên quan đến theo dõi sản xuất. Tôi làm việc cho một công ty kỹ thuật mô hình hóa và phân tích dữ liệu cho khách hàng của chúng tôi. Có một số bước trong quy trình và quy trình được cập nhật liên tục.

Tôi đang cố gắng mô hình hóa các quy trình và bao gồm các quy trình cha mẹ và thứ tự tuần tự của các quy trình.

Ví dụ:

Process Table
---------------------
ProcessID - uniqueidentifier
ProcessName - varchar
ProcessDescription - varchar
...

ProcessOrder Table
---------------------
ProcessID - uniqueidentifier FK - Process
ParentProcessID - uniqueidentifier FK - Process
ProcessOrder - int
...

Các ProcessOrdercột trong ProcessOrderbảng chỉ đơn giản là sẽ lưu trữ một số đại diện mà bước tuần tự trong quá trình mẹ nó đại diện.

Ví dụ, một quy trình mô hình hóa có các bước sau: tạo mô hình trống mới, mô hình tên, nhập tham số mô hình. Các Processbảng sẽ trông như thế:

ProcessID | ProcessName | ProcessDescription
-------------------------------------------------
UUID1     | Modeling    | Create Model of Data
UUID2     | New Model   | create new empty model
UUID3     | Name Model  | name model
UUID4     | Parameters  | enter model parameters

Các ProcessOrderbảng sẽ trông như thế:

ProcessID | ParentProcessID | ProcessOrder
--------------------------------------------------
UUID2     | UUID1           | 1
UUID3     | UUID1           | 2
UUID4     | UUID1           | 3

Vấn đề với thiết kế này là khi dòng công việc được cập nhật, thứ tự quy trình sẽ thay đổi và tôi sẽ cần cập nhật ProcessOrderbản ghi cho quy trình đã thay đổi và cho tất cả các bản ghi tiếp theo giống nhau ParentProcessID.

Có cách nào tốt hơn để lưu trữ loại dữ liệu này và duy trì chuẩn hóa?


Lưu ý nhỏ: các bảng ProcessOrder của bạn có PK được tạo không (có lẽ là GUID)? {Quá trình | ProcessOrder} có lẽ nên có một Vương quốc Anh, nhưng sẽ không lý tưởng vì là một PK được đưa ra các giá trị thay đổi trong ProcessOrder.
Jon của tất cả các giao dịch

Câu trả lời:


0

Thiết kế của bạn có vẻ hợp lý với tôi. Mặc dù bạn phải cập nhật tất cả các bản ghi tiếp theo khi các quy trình mới được thêm hoặc xóa dễ dàng thực hiện. Bạn chỉ cần phát hành một bản cập nhật như:

UPDATE ProcessOrder
SET ProcessOrder = ProcessOrder+1
WHERE ProcessOrder >= [step# where you want to insert]

và sau đó thực hiện chèn hoặc xóa của bạn.

Cách khác duy nhất tôi có thể nghĩ đến là thiết kế lược đồ để lưu trữ id tiến trình tiếp theo trên hàng. Cái gì đó như:

ProcessID | ParentProcessID | NextId
--------------------------------------------------
UUID2     | UUID1           | UUID3
UUID3     | UUID1           | UUID4
UUID4     | UUID1           | NULL

Sau đó, nếu bạn chèn một bước mới - giả sử giữa UUID3 và UUID4, bạn sẽ thực hiện thêm thao tác danh sách được liên kết sẽ cập nhật NextUd của UUID3 | UUID1 thành UUID5 và sau đó chỉ cần chèn UUID5 mới với UUID4 tiếp theo.

Điều này sẽ giảm CẬP NHẬT xuống 1 trong hầu hết các trường hợp, nhưng nó sẽ khiến việc truy vấn quá trình trở nên khó khăn hơn vì bây giờ bạn phải đi bộ danh sách từ trên xuống dưới để liệt kê từng bước.

Bạn cần quyết định quá trình nào bạn muốn ủng hộ - chèn và cập nhật hoặc truy xuất. Nếu bạn thích truy xuất (mà bạn có thể nếu các thay đổi không thường xuyên và báo cáo là thường xuyên và danh sách ngắn), thì hãy đi với thiết kế ban đầu của bạn. Nếu bạn thích chèn và cập nhật (mà bạn có thể thay đổi mọi lúc và báo cáo không thường xuyên hoặc danh sách thực sự dài), thì hãy đi theo cách tiếp cận danh sách được liên kết.

Tôi hi vọng cái này giúp được. Quan tâm đến những giải pháp khác mà cộng đồng có thể đưa ra vì tôi muốn mở rộng kiến ​​thức của mình xung quanh vấn đề này!


Cám ơn phản hồi của bạn. Nó rất hữu ích. Tôi nghĩ rằng tôi sẽ tập trung vào khía cạnh truy vấn của mọi thứ hơn là chèn hoặc cập nhật. Vì vậy, có vẻ như tôi nên sử dụng ví dụ đầu tiên của bạn. Bạn có thể tư vấn làm thế nào tôi có thể đưa tuyên bố cập nhật vào một kích hoạt?
Brian

Chèn sẽ vi phạm khóa chính của bạn, do đó bạn phải tạo một thay vì chèn kích hoạt. Trong trình kích hoạt đó, bạn sẽ phải kiểm tra xem bản ghi được chèn có vi phạm PK hay không và liệu nó có thực hiện cập nhật mà tôi đã mô tả bằng cách sử dụng ProcessOrder từ bảng INSERTED như bước # không. Sau đó thực hiện CHERTN. Để xóa, bạn sẽ cần phải viết trình kích hoạt TRƯỚC KHI XÓA sẽ thực hiện CẬP NHẬT mà tôi đã mô tả bằng cách sử dụng ProcessOrder từ bảng XÓA như bước #. Không cần kiểm tra. Bạn KHÔNG muốn có bất kỳ kích hoạt CẬP NHẬT nào vì chúng sẽ kích hoạt khi kích hoạt INS / DEL của bạn kích hoạt.
Todd Everett

1

Nếu tất cả những gì bạn cần là lưu trữ bước nào trong quy trình của bạn sau bước trước đó, thì tất cả những gì bạn cần là:

ProcessID | ParentProcessID | TrướcProcessID

Tất nhiên, bạn sẽ cần một ràng buộc FK để đảm bảo rằng (ParentProcessID | BeforeProcessID) trỏ đến hợp lệ (ParentProcessID | ProcessID)

Nếu tôi hiểu các yêu cầu của bạn và thiết kế này là hợp lệ, thì có thể dễ dàng chèn / xóa / di chuyển xung quanh các bước trong quy trình của bạn - bạn không phải truyền bất kỳ thay đổi nào cho các bảng con của mình, vì chúng tham chiếu đến khóa chính của bạn trên (ParentProcessID | ProcessID).

HIH


0

Vài câu hỏi đầu tiên ...

  1. Tại sao bạn sẽ sử dụng định danh duy nhất làm cột chính của mình? Tôi thấy điều này được thực hiện thường xuyên trong cơ sở dữ liệu và tôi không bao giờ chắc chắn tại sao. Nếu bạn thực sự cần một bản ghi là duy nhất trong toàn bộ cơ sở dữ liệu hoặc thậm chí trên nhiều hệ thống / cơ sở dữ liệu thì điều đó hoàn toàn tốt. Tuy nhiên, nếu đó không phải là trường hợp và bạn chỉ cần bản ghi là duy nhất trong bảng thì hãy sử dụng một giá trị số nguyên. Ngay cả khi bạn phải sử dụng BIGINT, bạn vẫn sẽ tốt hơn; một loại BIGINT là 8 byte trong khi UNIQUEIDENTIFIER được lưu trữ dưới dạng chuỗi nhị phân 16 byte.
  2. Quy trình công việc trông như thế nào ở cấp ứng dụng liên quan đến việc cập nhật thứ tự quy trình? Lý do tôi hỏi là vì bạn có thể tránh được nhiều câu lệnh CẬP NHẬT nếu bạn có thể lưu trữ mọi thứ trong bộ nhớ cục bộ cho đến khi quy trình làm việc hoàn tất. Ví dụ: nếu ứng dụng giao diện người dùng là ứng dụng Web ASP.NET, bạn có thể lưu trữ mọi thứ trong Trạng thái phiên, cho phép người dùng hoàn thành toàn bộ quy trình công việc và sau đó thực hiện một thao tác cơ sở dữ liệu.
  3. Có thể nhiều người dùng sẽ làm việc cùng lúc với các thành phần của quy trình? Nếu vậy, bạn sẽ cần đặt kiểm tra tại chỗ để đảm bảo hai người dùng không thể bước lên ngón chân của nhau.
  4. Điều gì về một lịch sử quá trình kiểm toán và báo cáo? Nếu bạn cập nhật hồ sơ thì bạn sẽ hoàn toàn mất tất cả lịch sử. Bạn sẽ không bao giờ có thể trình bày một báo cáo cho thấy các bước quy trình khác nhau, thời gian cần thiết để chuyển từ cái này sang cái khác, v.v.

Ba và bốn ở trên có thể được giải quyết bằng cách chèn các bản ghi cho mỗi thay đổi duy nhất thay vì cập nhật các bản ghi. Điều này rõ ràng sẽ tạo ra một tấn dữ liệu bổ sung, nhưng nó cũng sẽ cung cấp cho bạn rất nhiều thông tin chi tiết về chính quy trình công việc và cuối cùng cung cấp thông tin có thể được sử dụng để tạo xu hướng, PKI và thông tin kinh doanh khác, đưa chúng ta đến kho dữ liệu .. Nhưng đó là một bài viết khác.


0

Bước quy trình không có ý nghĩa trong trường hợp của bạn trừ khi phiên bản quy trình được xác định. Vì vậy, bạn có thể nói rằng quy trình 1 có các bước được thực hiện theo thứ tự này (a, b, d, c) khi quy trình ở phiên bản 1, nhưng trong phiên bản 2, thứ tự thực hiện bước thay đổi thành (a, b, c). Vì vậy, tôi nghĩ rằng một phiên bản quy trình là quan trọng.

Sơ đồ dưới đây đại diện cho đề nghị của tôi.

Điều ngớ ngẩn về điều này là nếu bạn thay đổi thứ tự của một bước, bạn phải chèn lại tất cả các bước theo thứ tự mới, nhưng trong trường hợp này, nó sẽ không thành vấn đề trong không gian hoặc thời gian.

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

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.