Khi nào một giá trị dữ liệu thực tế mã cứng vào mã trái ngược với việc sử dụng DB?


17

Một câu hỏi đã có từ lâu đối với tôi là: khi nào tôi lưu trữ dữ liệu (giá trị thực) trong bảng cơ sở dữ liệu và khi nào tôi lưu trữ chúng ngay trong mã?

Sự đồng thuận chưa được nói đến thường là như vậy (*):

Nếu nó là một biến đơn hoặc một cấu trúc đơn giản hoặc một mảng của một vài giá trị, hãy đặt dữ liệu ngay trong mã.

[* sự đồng thuận đã được tranh luận trong các bình luận và câu trả lời, nhưng về cơ bản tôi muốn có một tiền đề để bắt đầu câu hỏi, vì vậy hãy thoải mái thử thách và cải thiện nó ]

Thí dụ:

$number = 44;
$colors = array("blue", "yellow", ... "mauve");

Nếu nó có hàng trăm + hàng dữ liệu cùng loại, hãy sử dụng cơ sở dữ liệu.

Nhưng dường như có một khu vực màu xám; Còn những trường hợp không rõ ràng thì sao? Những cân nhắc và yếu tố nào người ta cần chú ý để đưa ra quyết định?

Ví dụ:
Giả sử công ty của bạn sử dụng 10-15 loại khung động cơ khác nhau có thể được biểu thị là "412T". Bạn có khoảng 30 người trong số họ và họ hiếm khi thay đổi. Bạn có thể tạo bảng DB cho những người đó hoặc mã cứng chúng trong cơ sở dữ liệu. Trong trường hợp này, động cơ là những thứ tĩnh, vật lý không có khả năng thay đổi thường xuyên.

Giữ chúng trong mã khiến chúng phải kiểm soát nguồn, trong đó trong cơ sở dữ liệu, các thay đổi DB thường không được theo dõi. Nhưng việc giữ chúng trong cơ sở dữ liệu sẽ giải phóng mã (tách) khỏi dữ liệu.

Một ví dụ (thực tế) khác mà tôi có thể sử dụng là câu hỏi này của tôi: /programming/26169751/how-to-best-get-the-data-out-of-a-lookup-table (hiện 48 hàng dữ liệu tùy chọn).


3
Sự đồng thuận chưa được nói đến thường KHÔNG như vậy: Nếu đó là một biến đơn hoặc một cấu trúc đơn giản hoặc một mảng của một vài giá trị, hãy đặt dữ liệu ngay trong mã.
Pieter B

Có một cách giữa: Dữ liệu được lưu trữ trong cơ sở dữ liệu. Sau đó, nó được trích xuất để viết mã nguồn (ví dụ, trong một global_constants.htệp).
mouviciel

@mouviciel nhưng những gì cấu thành dữ liệu ... bạn cần một số dữ liệu để truy cập cơ sở dữ liệu, vì vậy bạn không thể lưu trữ tất cả dữ liệu trong đó.
jwenting

Câu trả lời:


33

Tôi không nghĩ hai tuyên bố này thực sự thể hiện sự đồng thuận về thời điểm dữ liệu mã cứng:

Nếu nó là một biến đơn hoặc một cấu trúc đơn giản hoặc một mảng của một vài giá trị, hãy đặt dữ liệu ngay trong mã

Nếu nó có hàng trăm + hàng dữ liệu cùng loại, hãy sử dụng cơ sở dữ liệu

Ví dụ phản biện đơn giản (tôi chắc chắn có những cái tốt hơn): các bảng cú pháp ngôn ngữ lập trình là các cấu trúc lớn phức tạp thường được mã hóa cứng. Hãy xem một ví dụ từ mã nguồn Perl .

Thay vào đó tôi sẽ tập trung đầu tiên vào việc hỏi:

  • Làm thế nào thường xuyên thay đổi dữ liệu?

  • Ai có thể cần phải thay đổi nó?

Nếu câu trả lời cho "tần suất" là "thường xuyên hơn tôi muốn triển khai một phiên bản mới của ứng dụng của tôi", thì bạn không nên mã hóa dữ liệu.

Nếu câu trả lời cho "ai thay đổi nó" là "bất kỳ ai ngoài lập trình viên", thì bạn không nên cứng mã dữ liệu.

Trong một cửa hàng nhỏ, có thể sự khác biệt giữa người viết mã và người dùng đã biến mất và ý tưởng "triển khai" cũng biến mất. Trong trường hợp này, bạn là vua của tên miền của riêng bạn và bạn có thể làm bất cứ điều gì bạn thích.

Nhưng ngay cả trong tình huống đó, nhu cầu hợp tác có thể xuất hiện và điều đó có thể khó khăn nếu một ứng dụng tùy chỉnh không tuân theo quy ước mà các lập trình viên thường làm theo.


6
Tương tự như câu hỏi thường gặp, một câu hỏi khác là "Cần thay đổi nhanh như thế nào?" Yếu tố gating có thể là mất bao lâu để triển khai trên cơ sở người dùng của bạn. Đối với phần mềm máy chủ tập trung, câu trả lời có thể là vài phút, nhưng đối với các ứng dụng di động trong lĩnh vực này, có thể mất vài tuần.
CuriousRợi

Trong ví dụ về Perl, tôi sẽ đặt nó như là an array with a few values, một vài hàng có kiểu dữ liệu cơ bản là 377. Có thể nhiều hơn "một vài" với một số người, nhưng nó vẫn còn khá nhỏ. Tôi có cấu trúc tương tự nhưng hơi ít mã hóa cứng. Nếu nó là một ngàn + hàng, tôi có thể miễn cưỡng mã hóa nó theo cách này.
Dennis

14

Tôi sẽ đi với tùy chọn thứ ba: một tập tin cấu hình!

Đối với các ứng dụng mà tôi làm việc (trong Java, vì vậy tất cả các ví dụ của tôi đều sử dụng Java + Spring), các giá trị như vậy thường được lưu trữ trong các tệp cấu hình và được đưa vào (thông qua Spring) vào mã cần chúng khi ứng dụng khởi động. Trong tệp thuộc tính:

motorFramesString=412T, 413T, ...

Trong cấu hình mùa xuân:

<bean="motorFrameManager" class="myCompany.MotorFrameManager" >
    <property name="motorFrames" value="${motorFrames}"/>
</bean>

Ưu điểm của việc này là bạn có thể thay đổi hoặc thêm nhiều giá trị tĩnh này một cách dễ dàng, không cần biên dịch lại và bạn không phải lo lắng về việc điền vào cơ sở dữ liệu (quan hệ) của mình với dữ liệu tham chiếu (vì dường như đó là một quan tâm, và có lẽ không phải tất cả mọi thứ cần phải có trong cơ sở dữ liệu nào).

Về lý do tại sao các giá trị này nên đi vào tệp cấu hình thay vì bảng tham chiếu: Bạn có kế hoạch sử dụng các giá trị này chủ yếu trong mã hoặc chủ yếu trong cơ sở dữ liệu không? Nếu bạn có nhiều truy vấn và chế độ xem và quy trình hiện có phụ thuộc vào các giá trị này, thì tốt nhất nên đặt chúng vào cơ sở dữ liệu dưới dạng dữ liệu tham chiếu, vì sẽ dễ dàng hơn khi tải chúng từ tệp cấu hình và gửi chúng dưới dạng tham số cho mọi truy vấn có thể / xem / thủ tục tham chiếu chúng. Nếu các giá trị được sử dụng chủ yếu trong mã ứng dụng, thì tệp cấu hình có lẽ là lựa chọn tốt hơn.


Một ví dụ phức tạp hơn như những gì bạn liên kết cũng có thể được thực hiện, có hoặc không có thuộc tính.

Trong các sản phẩm. Sản phẩm:

productA.name=Product A 123
productA.hasMotor=true
productA.numFeet=1
productA.hasOutlet=true
productA.needsManual=true

productB.name=Product B 456
productB.hasMotor=false
productB.numFeet=1
productB.hasOutlet=true
productB.needsManual=true

Trong tập tin cấu hình mùa xuân của bạn:

<bean name="productA" class="com.mycompany.Product">
   <property name="name" value="${productA.name}"/>
   <property name="hasMotor" value="${productA.hasMotor}"/>
   <!-- rest omitted for brevity -->
</bean>
<bean name="productB" class="com.mycompany.Product">
   <property name="name" value="${productB.name}"/>
   <property name="hasMotor" value="${productB.hasMotor}"/>
   <!-- rest omitted for brevity -->
</bean>
<!-- configure as many beans as needed -->
<bean="motorFrameManager" class="myCompany.MotorFrameManager" >
    <property name="motorFrames"> <!-- assumes that MotorFrameManager has a property motorFrames which is a List<Product> -->
        <list>
            <ref bean="productA"/>
            <ref bean="productB"/>
        </list>
    </property>
</bean>

Điều thú vị ở đây là nếu dữ liệu nguồn của bạn là một bảng tính (như trong câu hỏi bạn đã liên kết), bạn có thể sử dụng macro trong Excel để tự động tạo các thuộc tính và đoạn trích mùa xuân.


trong khi bạn ở trên ví dụ khung, nó khá đơn giản (chỉ có một giá trị chuỗi). Cách tiếp cận của bạn về cơ bản là giống nhau cho bảng tùy chọn có n-tuples của các biến hỗn hợp (được liên kết ở cuối câu hỏi của tôi)?
Dennis

@Dennis: Đã thêm một ví dụ phức tạp hơn.
Thất vọngWithFormsDesigner

8
Một tệp cấu hình chỉ là một dạng của db.
DougM

3
@DougM, tôi đồng ý, nhưng có một thế giới khác biệt giữa việc thiết lập một loạt các bảng cấu hình trong Oracle và có một tệp cấu hình XML đơn giản. Các tập tin cấu hình cũng có ưu điểm là được kiểm soát bởi kiểm soát phiên bản. Các tập tin cấu hình là một trung gian và một trong đó khuyến khích các lập trình viên tách dữ liệu cấu hình ra nhiều hơn. Tôi đang vật lộn để nghĩ về các kịch bản thực tế trong đó thời gian không phải là một điều tốt
đánh bại

2
@gbjbaanb: Đối với hầu hết các ứng dụng, RDBMS là WAAAAAY quá mức cần thiết, ngay cả đối với các hệ thống khá rộng rãi. Chưa kể rằng chúng chậm và đòi hỏi một nỗ lực hợp lý để duy trì và hòa nhập. Các tệp "ini" không cung cấp bất kỳ loại an toàn nào, bạn phải tự viết trình phân tích cú pháp và bạn phải viết kiểm tra loại của riêng bạn. Các tệp Cấu hình XML, ít nhất là trong .Net, nhận được tất cả các lợi ích được cung cấp bởi một trong các tùy chọn ưa thích của bạn về cơ bản MIỄN PHÍ. Vì vậy, khẳng định của bạn rằng tệp cấu hình XML luôn là lựa chọn tồi tệ hơn không thể sai hơn.
Dunk

10

Tôi nghĩ tiền đề của câu hỏi không hoàn toàn đúng. Yếu tố phân chia không phải là số lượng hồ sơ cần thay đổi, mà là tần suất thay đổi cũng như ai thay đổi chúng.

Tần số

Khi dữ liệu không ổn định , theo nghĩa là nó thay đổi thường xuyên và nằm ngoài chu kỳ phát hành của phần mềm, nó cần phải được cấu hình bên ngoài các giá trị được mã hóa cứng hoặc thậm chí các tệp cấu hình. Một cơ sở dữ liệu có ý nghĩa ở đây, đặc biệt nếu bản thân ứng dụng có khả năng duy trì nó.

Ai

Khi một khách hàng cần có khả năng thay đổi dữ liệu, nó cần phải được sửa đổi theo cách thân thiện với người dùng và bên ngoài chu kỳ phát hành.

Chủ đề thông thường

Chủ đề phổ biến ở đây là khi dữ liệu cần thay đổi bên ngoài bản phát hành phần mềm, nó nên được lưu trữ trong cơ sở dữ liệu. Cơ sở dữ liệu có thể được nâng cấp trong khi phát hành, nhưng dữ liệu vẫn tồn tại mà không bị thiết lập lại hoặc sửa đổi nhiều. Khi một khách hàng cần có khả năng sửa đổi dữ liệu (hoặc cấu hình chức năng), nó sẽ được lưu trữ trong cơ sở dữ liệu với mặt trước đẹp mà không bị chứng minh.

Kiểm tra

Hãy chắc chắn viết các bài kiểm tra đơn vị xác nhận phần mềm của bạn trong nhiều cấu hình khác nhau. Có thể khách hàng của bạn bật một dấu nhắc tùy chọn hoặc xác định lại một mét bằng mười hai feet. Bất kể sự thay đổi đó hợp lý đến mức nào, nếu phần mềm của bạn cho phép nó, thì xác thực tốt hơn là sự thay đổi đó hoạt động như mong đợi cho dù nó có điên đến mức nào.


4

Đó không phải là tần suất thay đổi cũng như lượng dữ liệu quyết định nơi lưu trữ dữ liệu.

Nếu dữ liệu được yêu cầu để chạy chương trình, nó là một phần của mã chương trình, vì vậy hãy lưu trữ dưới dạng hằng số. Tất cả các dữ liệu khác đi trong cơ sở dữ liệu.

Tất nhiên, tập tin cấu hình, hình ảnh, âm thanh, vv thường được lưu trữ tốt hơn trên hệ thống tập tin.


Tôi đã thực hiện một chương trình hỗ trợ trung tâm cuộc gọi hoàn toàn do db điều khiển; dữ liệu được yêu cầu để "chạy mã", nhưng nó sẽ là vô lý để biên dịch nó.
DougM

1
Tôi đã là một nhà phát triển của Oracle trong 8 năm, nhưng tôi vẫn không thích các ứng dụng có sự kết hợp chặt chẽ như vậy với cơ sở dữ liệu cơ bản.
nháy mắt

2

Nếu thậm chí có một cơ hội nhỏ nhất bạn sẽ nhận được một cuộc gọi điện thoại dẫn đến việc bạn phải xây dựng lại một ứng dụng vì một cái gì đó được mã hóa cứng đã thay đổi, thì đừng mã hóa nó. Ít nhất hãy giữ nó trong một tệp cấu hình hoặc bảng db. Bạn không phải cung cấp bất kỳ giao diện người dùng nào để duy trì nó nhất thiết, nhưng quay số và thay đổi tệp cấu hình hoặc chạy SQL CẬP NHẬT trên một bảng chắc chắn là tốt hơn để xây dựng lại toàn bộ trận đấu.


1

Sự khác biệt thực sự là một khu vực hơi xám, nhưng cách tiếp cận của tôi đối với các loại vấn đề này là: liệu dữ liệu có thay đổi trong sản xuất không? "Bất cứ điều gì thay đổi sau khi triển khai trong môi trường sản xuất đều phải có trong cơ sở dữ liệu, ngay cả đối với những thứ hiếm khi thay đổi.

Vì vậy, câu hỏi bạn nên đặt ra không phải là "nó có thường xuyên thay đổi không?", Mà là "nó có thể thay đổi không?". Nếu một giá trị cho một thuộc tính có thể thay đổi trong cùng một lần lặp mã (mà không chạm vào bất cứ thứ gì khác trong mã) trên môi trường sản xuất, thì nó sẽ đi vào cơ sở dữ liệu.


0

Những gì bạn cũng thiếu là thông tin loại "điều khiển chương trình" cho biết kích thước bộ đệm tối đa, số lượng mục lớn theo thứ tự, kích thước trang tối đa cho màn hình luôn tốt hơn khi được mã hóa cứng trong chương trình hoặc trong tệp cấu hình.

Nếu bạn giữ loại dữ liệu này trong cơ sở dữ liệu, luôn có khả năng ai đó thay đổi dữ liệu một cách nhanh chóng và thay đổi hoàn toàn hành vi của một hệ thống.

Vấn đề khác là không có cách nào dễ dàng để có được các mục cơ sở dữ liệu thông qua hệ thống kiểm soát nguồn / quản lý thay đổi / hệ thống xây dựng tự động mà bạn nên sử dụng.


0

Một điều bạn không bao giờ nên giữ trong cơ sở dữ liệu là các chi tiết cần thiết để truy cập cơ sở dữ liệu.
Bạn đã có một chút lưu ý nếu bạn cần truy cập cơ sở dữ liệu để truy xuất chuỗi kết nối, tên người dùng và mật khẩu cho cùng một cơ sở dữ liệu đó.

Hardcode đó? hmm, có thể hoạt động nếu bạn đang sử dụng một số loại cơ sở dữ liệu cài đặt và vận chuyển cùng với ứng dụng.
Tập tin cấu hình? Hứa hẹn hơn nhưng bảo mật tài khoản thì sao?

Tất nhiên bạn có thể lưu trữ thông tin cơ sở dữ liệu trong tệp cấu hình đó ở dạng được mã hóa, nhưng sau đó bạn cần phải có các khóa giải mã được lưu trữ ở đâu đó và điều đó gần như chắc chắn được mã hóa.

Ngoài ra, có những thứ không bao giờ thay đổi. Những thứ như hằng số tự nhiên (G, pi, e, bạn đặt tên cho nó), những thứ có thể giống như một số biểu thức thông thường nhất định, như xác nhận email.

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.