Giữ enum và bảng đồng bộ


11

Tôi đang tạo một chương trình sẽ đăng dữ liệu lên cơ sở dữ liệu và tôi đã chạy theo một mẫu mà tôi chắc chắn là quen thuộc: Một bảng ngắn gồm các giá trị cố định rất có thể (rất có khả năng) đóng vai trò là một enum. Vì vậy, giả sử bảng sau đây được gọi là Status:

  Trạng thái
  Mô tả Id
  --------------
   0 Chưa xử lý
   1 chờ xử lý
   2 Đã xử lý
   3 lỗi

Trong chương trình của mình, tôi cần xác định Id trạng thái cho một bảng khác hoặc có thể cập nhật một bản ghi với Id trạng thái mới.

Tôi có thể mã hóa Id trạng thái trong một enum và hy vọng không ai thay đổi cơ sở dữ liệu. Hoặc tôi có thể pre-fetch các giá trị dựa trên mô tả (do đó hardcoding thay vào đó).

Điều gì sẽ là cách tiếp cận chính xác để giữ cho hai, enum và bảng, được đồng bộ hóa?


Tại sao bạn giữ mọi thứ đồng bộ và không đồng bộ? Đồng bộ (nói nó) là lạ!
MrFox

1
@suslik Cả hai đều phát âm giống nhau. SynchSync .
MPelletier

1
Có một enum và bảng cơ sở dữ liệu là trùng lặp. Trừ khi bảng cơ sở dữ liệu được sử dụng bởi các ứng dụng khác, tôi sẽ bỏ qua bảng và chỉ sử dụng enum. Nếu bảng sẽ được sử dụng trong nhiều ứng dụng, thay vào đó hãy tải các trạng thái từ cơ sở dữ liệu.
Peter Smith

Nó phụ thuộc vào ngữ cảnh. Trong trường hợp này, là giá trị trạng thái công việc hoặc trạng thái tác vụ, tôi có xu hướng ưu tiên giữ chúng động hơn tĩnh, vì các quy trình thường có xu hướng thay đổi; và có xu hướng thay đổi băng tần cho lịch phát hành phần mềm. Mặt khác, nếu dịch vụ ổn định không có khả năng loại bỏ các trạng thái mới hoặc trạng thái hiện tại, tôi có thể buộc phải mã hóa enum / không chuẩn hóa chúng (tùy thuộc vào cách sử dụng các bản ghi sau này).
JustinC

@PeterSmith Cơ sở dữ liệu không thể thực thi các ràng buộc nếu chúng chỉ có trong enum Java của bạn chứ không phải trong một bảng. Bạn sẽ hạn chế các giá trị trong cơ sở dữ liệu của bạn, phải không?
David Conrad

Câu trả lời:


5

Tôi sẽ mã hóa enum trong chương trình của bạn, vì tôi nghi ngờ những trạng thái khác nhau này ảnh hưởng đến logic chương trình của bạn. Nếu bạn có trạng thái mới, chương trình của bạn sẽ phản ứng thế nào với trạng thái mới này?

Bởi vì cơ sở dữ liệu là một phần của ứng dụng của bạn, tôi không nghĩ sẽ có ý nghĩa khi ảnh hưởng đến cái này mà không hỏi ý kiến ​​người khác.


Đó không phải là quá nhiều về các trạng thái mới (chắc chắn sẽ đảm bảo sửa đổi cả cơ sở dữ liệu và chương trình), nhưng các giá trị Id.
MPelletier

2
Tôi không thấy lý do tại sao bạn sẽ thay đổi giá trị ID mà không thay đổi ý nghĩa của nó. Các kiểu liệt kê này sẽ không được tự động tăng lên và chúng thực sự chỉ dành cho người đọc gỡ lỗi cơ sở dữ liệu, vì thông thường ứng dụng của bạn sẽ thực hiện truy vấn và sẽ biết ID pendingsẽ là gì. Tất nhiên có một Statusbảng cung cấp cho bạn tính toàn vẹn tham chiếu, nhưng đó là điểm tôi đang cố gắng thực hiện.
Matthew

Vâng, đó là ý tưởng. Nhưng nếu tôi đặt ID ở một nơi khác cho người khác, tôi sẽ giả định rằng cả hai đều đúng. Đó là một liên kết lỏng lẻo, phải không?
MPelletier

3
Chúng tôi luôn đưa ra các giả định này, nếu bạn nghĩ về định nghĩa bảng, chương trình của chúng tôi giả định định nghĩa là như vậy khi viết truy vấn. Các Statusbảng không nên được coi là năng động thông qua bộ thực thi của ứng dụng, và vì vậy tôi không nghĩ rằng bạn nên đọc nó như vậy.
Matthew

8

Tôi thường sẽ tải dữ liệu này vào bộ đệm tĩnh (thường là trong HashMap hoặc đại loại như thế) khi ứng dụng khởi động. Nó tránh phải biên dịch lại chỉ vì enum đã được sửa đổi theo một cách nào đó.


2

Vì đó là những trạng thái nên chúng được mã hóa cứng vào ứng dụng để đảm bảo không có thay đổi DB nào làm hỏng chương trình của bạn (ít nhất là không dễ dàng). Điều này rất quan trọng vì mọi trạng thái phải được thêm vào phải được mã hóa trước tiên và không chỉ đơn giản được thêm vào DB.

Bạn vẫn nên ghi các giá trị trạng thái đó vào DB với các mô tả chính xác của chúng trong trường hợp bạn cần lấy một báo cáo chẳng hạn.

Thông thường tôi có một đoạn mã nhỏ sẽ kết nối với DB và xác minh rằng tất cả các trạng thái được liệt kê trong một bảng cụ thể đều có cùng giá trị id / tên mà tôi đã mã hóa cứng trong bộ nhớ. Nếu chúng không khớp, tôi sẽ hủy bỏ việc thực thi phần mềm.

Tùy thuộc vào nhu cầu của bạn, bạn có thể muốn thực hiện các hành vi hơi khác nhau nhưng nhìn chung, dù sao đi nữa, những trạng thái đó được mã hóa cứng.


2

Chúng tôi có các vấn đề tương tự trong dự án của tôi (mã kế thừa, hooray!) Vấn đề chính là "các bảng enum không bao giờ thay đổi" cho đến khi chúng làm và mã bị hỏng. Tôi có hai chiến lược để giảm thiểu rằng tôi đã dần dần di chuyển tới.

Đầu tiên, và tốt nhất, là loại bỏ các tham chiếu trực tiếp đến các giá trị này bất cứ khi nào có thể. Luôn luôn hỏi, "tại sao tôi cần sử dụng trực tiếp giá trị enum?" Trong nhiều trường hợp, đây là một dấu hiệu cho thấy mã có quá nhiều giả định được mã hóa cứng hoặc đang cố thực hiện quá nhiều thao tác trên dữ liệu. Xem nếu bạn không thể tạo mối quan hệ tốt hơn trong cơ sở dữ liệu hoặc mã linh hoạt hơn để xử lý những gì đang bị thao túng.

Khi nó không hoạt động, tôi đi đến kế hoạch B: tạo mã. Vì các bảng thay đổi không thường xuyên và chúng tôi xuất bản các bản dựng mới thường xuyên, nên một trình tạo mã có thể đọc các bảng enum và viết mã enum. Thư viện được tạo động này sau đó được sử dụng trong dự án. Nếu DB thay đổi, bản dựng tiếp theo sẽ không biên dịch, điều này tốt hơn rất nhiều so với việc gặp lỗi thời gian chạy bí ẩn.


Làm thế nào bạn sẽ loại bỏ các tham chiếu đến một enum? Ví dụ: bạn đang sắp xếp hoặc tìm kiếm theo một trạng thái trong trường hợp này. Có một số giá trị ma thuật trong DB cũng không phù hợp với tôi. Đó là những gì bảng tra cứu dành cho.
nportelli

Trong quá khứ, tôi đã làm điều ngược lại. Bất cứ khi nào có sự thay đổi mã trong Enum, khi khởi động ứng dụng, nó sẽ đồng bộ các giá trị đó với Cơ sở dữ liệu. Ở đây mã là nguồn của sự thật. Cơ sở dữ liệu là một đại diện của nó. Thông thường tôi bỏ qua các giá trị trong DB mà mã không thể hiểu được nhưng bằng cách này, tôi có một cơ chế để tự động dọn sạch DB nếu cần.
Anshul
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.