Cách tốt nhất để tham chiếu dữ liệu tĩnh trong mã?


24

Nhiều ứng dụng bao gồm data dữ liệu tĩnh ': dữ liệu không thực sự thay đổi trong suốt vòng đời của ứng dụng. Ví dụ: bạn có thể có một danh sách Khu vực bán hàng có khả năng là danh sách cố định cho tương lai gần.

Không có gì lạ khi tìm thấy dữ liệu tĩnh này trong bảng cơ sở dữ liệu (thường là vì bạn muốn tham chiếu nó trong các khóa ngoài của các bảng khác). Một bảng ví dụ đơn giản sẽ có Id để sử dụng làm khóa chính và Mô tả. Ví dụ: bảng SalesArea của bạn sẽ có (ít nhất) một cột SalesAreaId và cột SalesAreaDes mô tả.

Bây giờ, trong mã bạn có thể không muốn xử lý mỗi hàng của bảng giống nhau. Ví dụ: bạn có thể muốn đặt Khu vực bán hàng mặc định trên một số màn hình, cung cấp các số liệu khác nhau cho một số khu vực hoặc hạn chế những gì người dùng có thể làm ở các khu vực khác.

Cách tốt nhất để tham khảo dữ liệu tĩnh này trong mã là gì? Tại sao?

  1. Mã cứng các mô tả trong mã của bạn. Sử dụng công cụ này để tra cứu SalesAreaId từ cơ sở dữ liệu khi bạn cần.
  2. Mã cứng ID trong mã của bạn. Sử dụng công cụ này để tra cứu SalesAreaDes mô tả khi bạn cần.
  3. Thêm một cột vào bảng cho từng mục đích, ví dụ: cột "IsDefaultOn ProducttLaunchScreen", v.v. (có thể có rất nhiều trong số này).
  4. Thứ gì khác.

Có bất kỳ cân nhắc đặc biệt nào khác mà tôi nên thực hiện khi xử lý dữ liệu tĩnh không? Ví dụ, đặt cho các bảng này một tên đặc biệt?


Câu trả lời:


14

Làm thế nào về việc tải chúng vào bộ đệm (thường được triển khai dưới dạng bảng băm) khi ứng dụng khởi động? Nếu bạn làm điều đó thì bạn thậm chí không phải truy vấn cơ sở dữ liệu (tốt, không quá một lần).

Tôi cũng sẽ đề nghị tránh mã hóa bất cứ điều gì. Thêm các chỉ báo mặc định (ban đầu trong bảng DB và cả trong cấu trúc bộ đệm) cho các màn hình cần mặc định. Để thực hiện tra cứu trên các lỗi không định nghĩa, hãy thử lưu trữ các khóa sẽ được tra cứu trong tệp cấu hình hoặc thuộc tính nếu bạn có thể.


Bộ nhớ đệm là tốt tất nhiên, nhưng làm thế nào để bạn cập nhật những giá trị này? Có lẽ là một ứng dụng khởi động lại, hoặc một số loại chiến lược vô hiệu hóa bộ đệm?
Steve

1
@Steve Vâng, chính xác. Phụ thuộc vào ứng dụng. Khởi động lại là tốt cho một cái gì đó bắt đầu thường xuyên. Đối với một ứng dụng chạy dài, có lẽ tải lại bộ nhớ cache mỗi ngày một lần trong thời gian chậm. Câu hỏi của tôi sẽ là, những gì về một kịch bản mà ứng dụng chạy nhiều thời gian rất ngắn. Giống như, có lẽ là một kịch bản PHP hoặc một cái gì đó tương tự.
tylermac

Cơ sở dữ liệu sẽ chạy bộ đệm riêng cho dữ liệu được truy cập thường xuyên, do đó bạn sẽ triển khai lại thứ gì đó đã được triển khai (và có thể không tốt!)
James Anderson

@JamesAnderson: Caching trong các phương tiện ứng dụng sẽ chỉ bao giờ là một cuộc gọi đến cơ sở dữ liệu. Có, cơ sở dữ liệu sẽ có bộ nhớ riêng nhưng chúng có thể bị vô hiệu / làm mới bởi các sự kiện nằm ngoài sự kiểm soát của ứng dụng của bạn và bạn vẫn phải có kết nối với cơ sở dữ liệu và thực hiện truy vấn để lấy dữ liệu đó (và hy vọng rằng nó có trong bộ nhớ cache của db). Thực sự không khó để thực hiện bộ đệm trong ứng dụng đơn giản.
Thất vọngWithFormsDesigner

7

Một thay thế cho DB hoặc mã hóa cứng là sử dụng tệp cấu hình được đọc tại thời điểm khởi động. Sau đó, bạn có thể lưu trữ dữ liệu này trong cấu trúc chỉ đọc trong mã của mình.

Trong trường hợp hiếm gặp (nhưng không phải là không thể) khi bạn chỉnh sửa dữ liệu này, bạn sẽ phải khởi động lại ứng dụng. Nếu điều này là không thể, bạn có thể viết một trình quản lý cấu hình phức tạp hơn để kiểm tra các thay đổi trong tệp cấu hình mỗi khi dữ liệu được truy cập, điều này thực sự khá hiệu quả vì bạn chỉ cần kiểm tra dấu thời gian trên tệp và sau đó vô hiệu hóa tất cả dữ liệu nếu tập tin được cập nhật.


1
Ý tưởng tốt cho một số loại dữ liệu tĩnh, nhưng không tốt lắm nếu bạn muốn thực thi các mối quan hệ FK như được mô tả trong câu hỏi.
Kramii phục hồi Monica

Câu hỏi không nói đây là một yêu cầu, chỉ là một kịch bản. Nếu không cần thiết thì cách tiếp cận tập tin cấu hình hoạt động tốt.
Steve

Bạn nói đúng, tôi không đủ rõ ràng. Nhưng tôi rất vui ... vì tôi đã học được điều gì đó từ câu trả lời của bạn. Tôi chưa bao giờ đi qua phương pháp này trước đây.
Kramii phục hồi Monica

3

Nếu dữ liệu liên quan đến dữ liệu hiện có trong DB của bạn, thì việc thêm nó vào DB cũng có hiệu quả như việc thêm nó vào mã. Nếu không thì tôi thường cố gắng "lấy viên đạn đó một lần" và đặt nó vào mã cho đến khi lần đầu tiên nó thay đổi.

Thông thường những gì chúng ta nghĩ sẽ là tĩnh hóa ra là không, và khi điều đó xảy ra, bạn không muốn phải chờ phát hành mã để thay đổi được thực hiện. Ngay khi điều đó xảy ra một lần, hãy đặt nó vào cơ sở dữ liệu và viết trang quản trị viên để cập nhật thêm.

Lấy ví dụ của bạn, nếu bạn đã có Khu vực bán hàng trong DB, hãy thêm một mô tả ở đó, đừng xây dựng bảng băm để liên kết dữ liệu cơ sở dữ liệu với các danh sách được mã hóa cứng. Nhưng nếu bạn không xây dựng bảng băm của Khu vực bán hàng bằng mọi cách, nhưng hãy sẵn sàng, lần đầu tiên ai đó thay đổi mô tả hoặc thêm Khu vực bán hàng mới, hãy chuyển nó sang DB.


"Thường thì những gì chúng ta nghĩ sẽ tĩnh không hóa ra" - rất đúng.
Kramii phục hồi Monica

3

Tại sao không chỉ mã cứng mọi thứ? Vấn đề chính tôi luôn gặp phải là tham chiếu các giá trị tĩnh từ DB trong mã ứng dụng. Đó là một điều nếu bạn chỉ trực tiếp xây dựng một danh sách thả xuống hoặc một cái gì đó ngoài các giá trị tĩnh, nhưng nếu logic ứng dụng nào đó phụ thuộc vào các giá trị từ DB thì sao?

Trong một ứng dụng đơn giản, tôi hiện có một danh sách các trạng thái chỉnh sửa cho các phần nội dung: Bản nháp, Xuất bản, Lưu trữ.

Các mục nội dung cần được xử lý khác nhau tùy thuộc vào trạng thái của chúng. Nếu tôi giữ dữ liệu trạng thái này trong DB, với các giá trị 1, 2, 3, tương ứng, tôi sẽ kiểm tra xem có gì trong Dự thảo không tiểu bang?

if (content.State == 1)
hay
if (content.State == "Draft")?

Tôi vừa mới mã hóa các giá trị!
Điều tương tự nếu bạn sử dụng bảng bộ đệm / băm: bạn vẫn phải sử dụng một số giá trị được ghi trong mã của bạn làm khóa để tra cứu dữ liệu của bạn.

Những bất lợi cho aproach mã hóa cứng là gì?


Nhược điểm là như pdr đã nói, "Thông thường những gì chúng ta nghĩ sẽ tĩnh không hóa ra".
tylermac

2
Nhưng nếu bạn thực sự tham khảo các giá trị dữ liệu tĩnh trong mã, bạn không thể thay đổi nó trong cơ sở dữ liệu mà không phá vỡ ứng dụng. Để chắc chắn, nó phụ thuộc vào dữ liệu đang được sử dụng cho mục đích gì: như tôi đã đề cập ở trên, nếu nó chỉ điền một phần tử UI để người dùng có thể chọn một giá trị và đưa nó trở lại DB như một phần của bản ghi trong bảng khác , sau đó dữ liệu tĩnh trong DB có thể thay đổi độc lập với mã ứng dụng. Tôi khá chắc chắn rằng tình huống mà @pdr đang nói đến: ứng dụng xử lý tập dữ liệu tĩnh dưới dạng một mục.
Dave

2

Tương tự như FrustratedWithFormsDesigner đã nói, việc này thường được thực hiện với bộ đệm, vì điều đó có nghĩa là bạn chỉ phải tải dữ liệu tĩnh một lần, nhưng nó tuân theo mẫu OAOO, có nghĩa là chúng tôi không xác định dữ liệu ở hai nơi (cơ sở dữ liệu và trong ma cua ban).

Tôi biết ORM NHibernate cung cấp chức năng này thông qua bộ đệm cấp 2 . Bạn có thể bảo nó lưu dữ liệu từ một bảng nhất định và nói rằng nó chỉ đọc. Nó sẽ được tải lần đầu tiên khi được yêu cầu và sẽ không truy cập lại cơ sở dữ liệu sau đó, ngay cả khi bạn truy cập dữ liệu từ nhiều phiên.


+1 cho một lần và chỉ một lần. Nhưng những gì về việc đối xử với các hàng khác nhau khác nhau?
Kramii phục hồi Monica

1
@Kramii - Bạn có thể sử dụng một cái gì đó như các lớp liệt kê . Nếu siêu dữ liệu chỉ liên quan đến chương trình của bạn, thì tôi sẽ đặt logic nghiệp vụ ( IsDefaultOn...) vào một thuộc tính trên thực thể. Có nó trả về đúng cho một thực thể. Điều đó sẽ cho phép bạn tìm thấy thực thể đó, với toàn bộ bộ sưu tập. Hoặc bạn có thể sử dụng một lớp trình điều khiển sẽ cung cấp cho bạn thực thể phù hợp với một cuộc gọi phương thức.
Scott Whitlock

2

Đây là tối ưu hóa sớm ở mức tồi tệ hơn của nó.

Đầu tiên, bất kỳ DBMS hiện đại nào cũng sẽ truy xuất dữ liệu từ các bảng nhỏ với tốc độ cực nhanh và tất cả chúng đều có các thuật toán lưu trữ từ tốt đến tuyệt vời (bạn càng trả nhiều tiền cho DBMS thì bộ đệm càng tốt!). Vì vậy, bạn đang tối ưu hóa một cái gì đó tiêu thụ tài nguyên tối thiểu.

Thứ hai, bạn có rất ít kinh nghiệm về các ứng dụng kinh doanh trong thế giới thực nếu bạn tưởng tượng một thứ như "khu vực bán hàng" là dữ liệu tĩnh. Đây là những trách nhiệm thay đổi với mỗi thay đổi của Giám đốc tiếp thị hoặc Giám đốc điều hành. Vì vậy, bạn đang hướng đến một thế giới đau khổ hai năm sau.

Chỉ có hai cách để đi đến đây: -

Lưu trữ nó trong cơ sở dữ liệu và truy cập dữ liệu với sql "bình thường".

Lưu trữ nó trong một tệp cấu hình XML ưa thích (có thể được truy cập qua REST hoặc SOAP) có thể dễ dàng chỉnh sửa bất cứ khi nào có "thay đổi chính sách chiến lược".


1

Nó phụ thuộc vào những gì bạn đang làm với dữ liệu. Nếu nó là một danh sách của một cái gì đó tôi thường sẽ kéo nó vào một mảng. Nếu danh sách cần phát triển trong một phiên bản khác, thật dễ dàng chỉ cần thêm vào cơ sở dữ liệu và thay đổi mã để xử lý dữ liệu bổ sung trong mảng (có thể không cần thiết tùy thuộc vào mã, ví dụ: liệt kê dữ liệu bằng một cho vòng lặp sử dụng giới hạn trên của mảng). Nếu đó là danh sách các cài đặt, tôi thường sẽ viết mã cứng vì thường không có nhiều và dễ dàng và nhanh hơn so với sử dụng câu lệnh SQL. Nếu đó là một cài đặt mà người dùng có thể thay đổi và tôi muốn lưu lựa chọn cho các lần khởi chạy tiếp theo, tôi sẽ tạo một bảng để sử dụng làm sổ đăng ký và chỉ cần kéo các mục riêng lẻ vào các biến khi cần.


1

Tôi biết câu trả lời này đã được chấp nhận nhưng tôi muốn chia sẻ cách chúng tôi đã làm điều này tại cửa hàng phát triển web cuối cùng của tôi, nơi chúng tôi đã cố gắng giảm cơ sở dữ liệu I / O càng nhiều càng tốt.

Chúng tôi đã sử dụng phía máy chủ bao gồm các tệp để tìm kiếm nhiều cấu trúc dữ liệu mà chúng tôi có thể. Chủ yếu điều này là để điều hướng trang web (bao gồm cả mạng con) nhưng chúng tôi cũng đã sử dụng nó cho càng nhiều lần thả xuống và hộp kiểm càng tốt (Bang, Quốc gia, Danh mục).

Ban đầu, chúng tôi đã lấy tất cả dữ liệu này từ cơ sở dữ liệu. Vì chúng tôi đã cung cấp cho khách hàng một tiện ích quản trị viên, họ có thể thay đổi dữ liệu này theo ý muốn và chúng tôi không bao giờ bị sa lầy với những thay đổi nhỏ. Hầu hết thời gian dữ liệu này hầu như không bao giờ thay đổi, nhưng về mặt thực tế, nó sẽ thay đổi.

Chúng tôi luôn tìm kiếm thời gian tải nhanh hơn. Vì vậy, chúng tôi quyết định thực hiện càng nhiều tệp văn bản phía máy chủ tĩnh càng tốt. Chúng tôi đã làm điều này trong các tiện ích quản trị. Mỗi khi bảng cơ sở dữ liệu được cập nhật, chúng tôi sẽ tạo lại tệp văn bản tĩnh tương ứng. Điều này đã cho chúng tôi một môi trường rất linh hoạt và nhanh chóng.


0

Giải pháp của tôi cho vấn đề này, có thể không hoạt động trong mọi tình huống, là liên kết dữ liệu cơ sở dữ liệu tĩnh với mã hóa cứng enum. Vì vấn đề xuất phát từ việc dữ liệu động (cơ sở dữ liệu) bị ràng buộc với logic tĩnh (mã), hãy làm cho ràng buộc này rõ ràng (và lỏng lẻo) bằng cách có một bảng cơ sở dữ liệu liên kết với enum. Vd

LooseDBCodeBinding (database table)
   ID : Int32 (key)
   Name : String
   HardCodedTypeID : Int32

// in code:
public enum LooseDBCodeBinding
{
   TYPE_1 = 1,
   TYPE_2 = 2,
   TYPE_3 = 3 // etc...
}

Sau đó, viết một giao diện người dùng cho phép bạn dễ dàng xem danh sách các LooseDBCodeBindingbản ghi và ánh xạ chúng tới LooseDBCodeBinding enumcác giá trị (bao gồm hỗ trợ các ràng buộc "bị hỏng"). Sau đó, bạn có thể lập trình xung quanh enumvà thiết kế cơ sở dữ liệu xung quanh phím bảng và đây chỉ là một bảng có kiến ​​thức về cả hai bối cảnh.

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.