Tôi nên xác định mối quan hệ giữa các bảng trong cơ sở dữ liệu hay chỉ trong mã?


60

Theo kinh nghiệm của tôi, nhiều dự án tôi đã đọc trong quá khứ không có định nghĩa mối quan hệ trong cơ sở dữ liệu, thay vào đó họ chỉ định nghĩa chúng trong mã nguồn. Vì vậy, tôi tự hỏi những lợi thế / bất lợi của việc xác định mối quan hệ giữa các bảng trong cơ sở dữ liệu và trong mã nguồn là gì? Và câu hỏi rộng hơn là về các tính năng nâng cao khác trong cơ sở dữ liệu hiện đại như tầng, trình kích hoạt, quy trình ... Có một số điểm trong suy nghĩ của tôi:

Trong cơ sở dữ liệu:

  • Dữ liệu chính xác từ thiết kế. Ngăn chặn các lỗi ứng dụng có thể gây ra dữ liệu không hợp lệ.

  • Giảm chuyến đi khứ hồi mạng cho ứng dụng khi chèn / cập nhật dữ liệu vì ứng dụng phải tạo thêm truy vấn để kiểm tra tính toàn vẹn dữ liệu.

Trong mã nguồn:

  • Linh hoạt hơn.

  • Tốt hơn khi nhân rộng ra nhiều cơ sở dữ liệu, vì đôi khi mối quan hệ có thể là cơ sở dữ liệu chéo.

  • Kiểm soát nhiều hơn về tính toàn vẹn dữ liệu. Cơ sở dữ liệu không phải kiểm tra mỗi khi ứng dụng sửa đổi dữ liệu (độ phức tạp có thể là O (n) hoặc O (n log n) (?)). Thay vào đó, nó được ủy quyền cho ứng dụng. Và tôi nghĩ rằng việc xử lý tính toàn vẹn dữ liệu trong ứng dụng sẽ dẫn đến nhiều thông báo lỗi dài hơn so với sử dụng cơ sở dữ liệu. Ví dụ: khi bạn tạo một máy chủ API, nếu bạn xác định các mối quan hệ trong cơ sở dữ liệu và có lỗi xảy ra (như thực thể được tham chiếu không tồn tại), bạn sẽ nhận được một Ngoại lệ SQL với một thông báo. Cách đơn giản sẽ là trả lại 500 cho khách hàng rằng có "lỗi máy chủ nội bộ" và khách hàng sẽ không biết chuyện gì đang xảy ra. Hoặc máy chủ có thể phân tích thông điệp để tìm ra những gì sai, đó là một cách xấu, dễ bị lỗi theo ý kiến ​​của tôi. Nếu bạn để ứng dụng xử lý việc này,

Có gì khác?

Chỉnh sửa: như Kilian chỉ ra, quan điểm của tôi về hiệu suất và tính toàn vẹn dữ liệu là rất sai lầm. Vì vậy, tôi chỉnh sửa để sửa quan điểm của tôi ở đó. Tôi hoàn toàn hiểu rằng để cho cơ sở dữ liệu xử lý nó sẽ là một cách tiếp cận hiệu quả và mạnh mẽ hơn. Vui lòng kiểm tra câu hỏi cập nhật và đưa ra một số suy nghĩ về nó.

Chỉnh sửa: cảm ơn mọi người. Các câu trả lời tôi nhận được đều chỉ ra rằng các ràng buộc / quan hệ phải được xác định trong cơ sở dữ liệu. :). Tôi có thêm một câu hỏi, vì nó nằm ngoài phạm vi của câu hỏi này, tôi vừa đăng nó dưới dạng một câu hỏi riêng biệt: Xử lý lỗi cơ sở dữ liệu cho máy chủ API . Xin hãy để lại một số hiểu biết.


4
"vì ứng dụng phải tạo thêm (các) truy vấn để kiểm tra tính toàn vẹn dữ liệu." Không cần thiết. Nếu cơ sở dữ liệu hoàn toàn nằm dưới sự kiểm soát của ứng dụng của bạn, việc kiểm tra thêm về tính toàn vẹn dữ liệu có thể là chương trình phòng thủ quá mức. Bạn không nhất thiết cần chúng; chỉ cần kiểm tra ứng dụng của bạn một cách thích hợp để đảm bảo nó chỉ thực hiện các thay đổi hợp lệ cho cơ sở dữ liệu.

9
Có một điều bạn không bao giờ nên quên: Trừ khi mọi người tham gia viết phần mềm hoàn hảo, nếu kiểm tra nằm trong phần mềm, một trong những kiểm tra này sẽ thất bại và dẫn đến các ràng buộc không được thi hành. Đó không phải là câu hỏi nếu, mà là khi nào. Điều này dẫn đến khó tái tạo lỗi và kéo dài hàng giờ dữ liệu để phù hợp với các ràng buộc được thi hành phần mềm một lần nữa.
Dabu

10
Một cái gì đó đáng nói ... một khi bạn giới thiệu các vấn đề về tính toàn vẹn cho cơ sở dữ liệu của mình, thì đó là người thân để mở hộp Pandora. Đó là một cơn ác mộng để giới thiệu lại tính toàn vẹn cho cơ sở dữ liệu dị thường. Giữ các kiểm soát chặt chẽ trên cơ sở dữ liệu của bạn có thể là một rắc rối nhưng nó sẽ giúp bạn tiết kiệm rất nhiều đau đớn trong thời gian dài.
DanK

3
Trong mã nguồn: Cuối cùng, bạn cuối cùng đã viết hầu hết các cơ sở dữ liệu.
Blrfl

7
Có lần tôi đã hỏi một lập trình viên rất tài năng một câu hỏi tương tự anh ta nói với tôi "Nó giống như phanh trên xe hơi. Điểm không phải là làm cho xe đi chậm hơn, mà là cho phép nó đi nhanh hơn an toàn hơn." Chắc chắn có thể của nó để chạy mà không có trở ngại nhưng nếu dữ liệu xấu bằng cách nào đó được vào, nó có thể gây ra một vụ tai nạn nghiêm trọng
lanh lợi

Câu trả lời:


70

TL; DR: Các ràng buộc về mối quan hệ nên có trong cơ sở dữ liệu.


Ứng dụng của bạn không đủ lớn.

Thật vậy, bạn đã đúng, rằng việc thực thi các mối quan hệ trên cơ sở dữ liệu có thể yêu cầu thực thi chúng trong ứng dụng.

Tuy nhiên, tôi sẽ chỉ ra rằng trước tiên bạn nên kiểm tra tài liệu của phần mềm cơ sở dữ liệu bạn đang sử dụng và kiểm tra các ưu đãi sản phẩm hiện có. Ví dụ: có các ưu đãi phân cụm trên đầu trang của Postgres và MySQL.

Và ngay cả khi bạn cuối cùng cần phải có một số xác nhận trong ứng dụng, đừng vứt em bé bằng nước tắm . Rốt cuộc, bạn càng ít phải làm, bạn càng có lợi.

Cuối cùng, nếu bạn lo lắng về các vấn đề về khả năng mở rộng trong tương lai, tôi e rằng ứng dụng của bạn sẽ phải trải qua những thay đổi đáng kể trước khi nó có thể mở rộng quy mô. Theo nguyên tắc thông thường, mỗi khi bạn tăng gấp 10 lần, bạn phải thiết kế lại ... vì vậy, đừng để quá nhiều tiền vào việc không lường trước được các vấn đề về khả năng mở rộng, và thay vào đó hãy sử dụng tiền để thực sự đạt đến điểm mà bạn gặp phải những vấn đề đó.

Ứng dụng của bạn không đủ chính xác.

Cơ hội mà cơ sở dữ liệu bạn sử dụng có lỗi thực hiện kiểm tra so với khả năng ứng dụng của bạn có lỗi thực hiện kiểm tra là gì?

Và cái nào làm bạn thay đổi thường xuyên nhất?

Tôi đặt cược vào cơ sở dữ liệu là chính xác, bất cứ lúc nào .

Các nhà phát triển của bạn không nghĩ rằng phân phối đủ.

Giảm chuyến đi khứ hồi mạng cho ứng dụng khi chèn / cập nhật dữ liệu vì ứng dụng phải thực hiện nhiều truy vấn hơn để kiểm tra tính toàn vẹn dữ liệu.

Cờ đỏ ! 1

Nếu bạn đang nghĩ:

  • kiểm tra nếu bản ghi tồn tại
  • nếu không, chèn bản ghi

sau đó bạn đã thất bại trong vấn đề tương tranh cơ bản nhất: một tiến trình / luồng khác có thể sẽ thêm bản ghi khi bạn đi.

Nếu bạn đang nghĩ:

  • kiểm tra nếu bản ghi tồn tại
  • nếu không, chèn bản ghi
  • kiểm tra nếu bản ghi được chèn vào như một bản sao

sau đó bạn không thể tính đến MVCC: chế độ xem cơ sở dữ liệu mà bạn có là ảnh chụp nhanh tại thời điểm giao dịch của bạn bắt đầu; nó không hiển thị tất cả các cập nhật đang xảy ra và thậm chí có thể không được cam kết.

Duy trì các ràng buộc trong nhiều phiên là một vấn đề thực sự khó khăn, hãy vui mừng vì nó đã được giải quyết trong cơ sở dữ liệu của bạn.

1 Trừ khi cơ sở dữ liệu của bạn thực hiện đúng thuộc tính Nối tiếp; nhưng ít người thực sự làm


Cuối cùng:

Và tôi nghĩ rằng, xử lý tính toàn vẹn dữ liệu trong ứng dụng sẽ cho phép thông báo lỗi dài hơn so với sử dụng cơ sở dữ liệu. Ví dụ: khi bạn tạo một máy chủ API. Nếu bạn xác định các mối quan hệ trong cơ sở dữ liệu và có lỗi xảy ra (như thực thể được tham chiếu không tồn tại), bạn sẽ nhận được một Ngoại lệ SQL với thông báo.

Không phân tích các thông báo lỗi , nếu bạn sử dụng bất kỳ cơ sở dữ liệu cấp sản xuất nào, nó sẽ trả về các lỗi có cấu trúc. Ít nhất, bạn sẽ có một số mã lỗi để chỉ ra những gì có thể sai và dựa trên mã này, bạn có thể tạo một thông báo lỗi phù hợp.

Lưu ý rằng hầu hết các lần mã là đủ: nếu bạn có mã lỗi cho bạn biết rằng khóa ngoại được tham chiếu không tồn tại, thì có khả năng bảng này chỉ có một khóa ngoại, vì vậy bạn biết trong mã đó là vấn đề gì .

Ngoài ra, và hãy trung thực ở đây, hầu hết các lần bạn sẽ không xử lý các lỗi một cách duyên dáng. Chỉ vì có rất nhiều người trong số họ và bạn sẽ không tính đến tất cả ...

... mà chỉ liên quan đến điểm chính xác ở trên. Mỗi lần bạn nhìn thấy "500: Lỗi máy chủ nội bộ" do ràng buộc cơ sở dữ liệu được kích hoạt và không được xử lý, điều đó có nghĩa là cơ sở dữ liệu đã lưu bạn, vì bạn chỉ quên xử lý nó trong mã.


3
Haha, bạn đã viết điều này khi tôi đang viết bình luận của mình, mỉa mai nhấn mạnh điểm chúng ta đang thực hiện. Tôi hoàn toàn đồng ý: Bạn thậm chí không thể thực hiện toàn vẹn hoặc ràng buộc trong mã không DB. Giao dịch không thể thấy kết quả của người khác cho đến khi họ cam kết (và thậm chí sau đó có thể không). Bạn có thể ảo tưởng về tính toàn vẹn nhưng nó có thể gặp vấn đề về thời gian hoặc khả năng mở rộng nghiêm trọng do khóa. Chỉ có cơ sở dữ liệu có thể làm điều này một cách chính xác.
LoztInSpace

8
Tất cả những điểm tốt. Một điều nữa là các mối quan hệ trong cơ sở dữ liệu là tài liệu tự. Nếu bạn đã từng phải thiết kế ngược lại một cơ sở dữ liệu chỉ có các mối quan hệ được xác định trong mã truy vấn nó, bạn sẽ ghét bất cứ ai làm theo cách đó.
Kat

1
@ Kat11: Đó là sự thật. Và tự mô tả cũng có lợi thế là các công cụ có thể dễ dàng hiểu dữ liệu và hành động trên nó, đôi khi có thể hữu ích.
Matthieu M.

1
Đối số của bạn về MVCC là không chính xác trong các DB thực hiện cách ly SERIALIZABLE một cách chính xác (ví dụ, các phiên bản hiện đại của PostgreQuery làm - mặc dù nhiều RDBMS chính không). Trong một DB như vậy, ngay cả cách tiếp cận đầu tiên, ngây thơ, sẽ hoạt động chính xác - nếu viết xung đột, chúng sẽ bị đẩy lùi như một lỗi nối tiếp.
James_pic

1
Trong các DB triển khai SERIALIZABLE chính xác, nếu bạn thực hiện tất cả các giao dịch được cam kết thành công, thì sẽ có một số thứ tự (có thể không giống như đặt hàng đồng hồ treo tường), như vậy nếu bạn đã chạy tất cả chúng một cách thanh toán (không có sự tương tranh) theo thứ tự đó, tất cả các kết quả sẽ giống hệt nhau. Thật khó để hiểu đúng và các thông số kỹ thuật SQL đủ mơ hồ để bạn có thể thuyết phục bản thân rằng không cho phép viết sai ở cấp SERIALIZABLE, vì vậy nhiều nhà cung cấp DB coi SERIALIZABLE là SNAPSHOT ISOLATION (Tôi đang nhìn vào Oracle của bạn).
James_pic

119

Cơ sở dữ liệu không phải kiểm tra tính toàn vẹn dữ liệu mỗi khi ứng dụng sửa đổi dữ liệu.

Đây là một điểm sai lầm sâu sắc. Cơ sở dữ liệu được tạo ra cho chính xác mục đích này. Nếu bạn cần kiểm tra tính toàn vẹn dữ liệu (và nếu bạn nghĩ rằng bạn không cần chúng, có lẽ bạn đã nhầm), thì hãy để cơ sở dữ liệu xử lý chúng gần như chắc chắn hiệu quả hơn và ít bị lỗi hơn so với thực hiện theo logic ứng dụng.


5
@ dan1111 Tôi không hiểu nhận xét của bạn ... bạn có nói: các ràng buộc đơn giản được thi hành bởi cơ sở dữ liệu, vì vậy chúng không phải là vấn đề đối với mã ứng dụng, các ràng buộc phức tạp hơn quá khó để thực hiện vì vậy chỉ cần từ bỏ chúng? Hoặc bạn đang nói rằng việc thực hiện các ràng buộc phức tạp bằng cách sử dụng các kích hoạt cơ sở dữ liệu (và cơ chế tương tự) là quá phức tạp và vì vậy tốt hơn là thực hiện chúng trong mã ứng dụng?
Bakuriu

47
Bạn thậm chí không thể thực hiện toàn vẹn hoặc các ràng buộc trong mã không DB. Giao dịch không thể thấy kết quả của người khác cho đến khi họ cam kết (và thậm chí sau đó có thể không). Bạn có thể ảo tưởng về tính toàn vẹn nhưng nó có thể gặp vấn đề về thời gian hoặc khả năng mở rộng nghiêm trọng do khóa. Chỉ có cơ sở dữ liệu có thể làm điều này một cách chính xác.
LoztInSpace

17
Thông thường, để theo dõi từ nhận xét của @ LoztInSpace, tôi đã từng làm việc cho một công ty (khủng khiếp) nơi một trong những bảng đó được thiết lập theo cách thay vì để DB tự động tăng ID, ứng dụng đã lấy ID hàng cuối cùng, đã thêm một cái vào đó và sử dụng nó làm ID mới. Thật không may, khoảng một tuần một lần ID trùng lặp đã được đưa vào khiến ứng dụng bị
sập

9
@ dan1111 Bạn không bao giờ viết lỗi trong ứng dụng, phải không?
dùng253751

4
@DavidPacker Tôi có thể đồng ý, tuy nhiên một khi bạn có nhiều máy khách truy cập cơ sở dữ liệu, bạn chỉ có thể thực thi các ràng buộc trong cơ sở dữ liệu. Trừ khi, đó là, bạn bắt đầu khóa các bảng bán buôn thay vì theo hàng, với hiệu năng đạt được.
Iker

51

Các ràng buộc phải nằm trong cơ sở dữ liệu của bạn, vì (với ý chí tốt nhất trên thế giới), ứng dụng của bạn sẽ không phải là điều duy nhất để truy cập cơ sở dữ liệu này.

Tại một số điểm, có thể cần phải sửa lỗi theo kịch bản trong cơ sở dữ liệu hoặc bạn có thể cần di chuyển dữ liệu từ bảng này sang bảng khác khi triển khai.

Ngoài ra, bạn có thể nhận được các yêu cầu khác, ví dụ: "Khách hàng lớn X thực sự cần bảng dữ liệu excel này được nhập vào cơ sở dữ liệu ứng dụng của chúng tôi vào chiều nay", nơi bạn sẽ không phải điều chỉnh mã ứng dụng của mình cho phù hợp khi tập lệnh SQL bẩn sẽ hoàn thành đúng giờ.

Đây là nơi toàn vẹn mức cơ sở dữ liệu sẽ tiết kiệm thịt xông khói của bạn.


Ngoài ra, hãy hình dung nhà phát triển đảm nhận vai trò của bạn tại công ty này sau khi bạn rời đi và sau đó được giao nhiệm vụ thay đổi cơ sở dữ liệu.

Anh ta sẽ ghét bạn nếu không có ràng buộc FK trong cơ sở dữ liệu để anh ta có thể cho biết bảng có mối quan hệ nào trước khi anh ta thay đổi nó? ( Manh mối, câu trả lời là có )


33
Ô anh trai. Tôi không thể nói với bạn bao nhiêu lần tôi phải giải thích với mọi người rằng cơ sở dữ liệu có nhiều khách hàng! Ngay cả khi ngay bây giờ chỉ có một khách hàng và chỉ có một con đường cho dữ liệu vào hệ thống, thiết kế ứng dụng và lược đồ của bạn dựa trên giả định này là cách tốt nhất để Future Yoshi ghét Past Yoshi.
Greg Burghardt

9
@nikonyrh Tôi sẽ không làm điều đó. Các ràng buộc là có để các ứng dụng có thể dựa vào dữ liệu nhất quán. Để vô hiệu hóa FK 'chỉ để đưa nó vào' là sự điên rồ.
Thóc

5
Đã đồng ý. Ngoài ra, ngay cả khi ứng dụng của bạn là máy khách duy nhất, bạn có thể có các phiên bản khác nhau của ứng dụng của mình đang cố thực thi các ràng buộc hơi khác nhau. Thông thường, sự vui nhộn xảy ra (tốt, không thực sự. Nó giống như 'sự hỗn loạn và thất vọng hoàn toàn' hơn là 'sự vui nhộn').
Iker

5
Tôi hoàn toàn có thể chứng thực điều này. Trong trường hợp của tôi, tôi đã bị kẹt trên MyISAM không thực sự hỗ trợ khóa ngoại, vì vậy tôi đã kết thúc với 250GB dữ liệu với tính toàn vẹn được thi hành bởi ứng dụng. Khi bắt đầu cắt tỉa dữ liệu để đưa hồ sơ tồn đọng đến kích thước dễ quản lý hơn và khi rõ ràng rằng chính ứng dụng sẽ không thể xử lý việc này, sự hỗn loạn xảy ra. Tôi không biết tại sao tôi sử dụng thì quá khứ; này vẫn xảy ra hiện nay và vấn đề (hai năm trên) vẫn chưa được giải quyết. * sụt sịt *
Cuộc đua nhẹ nhàng với Monica

1
Tôi sẽ lập luận rằng một cơ sở mã tốt sẽ giúp bạn dễ dàng viết một tập lệnh một lần bằng cách sử dụng lớp kiên trì từ ứng dụng của bạn ít nhất là nhanh như viết SQL thô. 'Sửa đổi mã ứng dụng của bạn' không bao giờ cần thiết cho các tập lệnh một lần.
Jonathan Cast

17

Bạn nên có quan hệ trong cơ sở dữ liệu.

Như các câu trả lời khác lưu ý, hiệu năng kiểm tra ràng buộc sẽ tốt hơn nhiều trong cơ sở dữ liệu đó so với bên trong ứng dụng của bạn. Kiểm tra ràng buộc cơ sở dữ liệu là một trong những điều mà cơ sở dữ liệu tốt.

Nếu bạn cần sự linh hoạt bổ sung - ví dụ: các tham chiếu cơ sở dữ liệu chéo được ghi chú của bạn - thì bạn có thể loại bỏ các ràng buộc một cách có chủ ý và cân nhắc. Có tính nhất quán trong cơ sở dữ liệu của bạn có nghĩa là bạn có tùy chọn sửa đổi các ràng buộc đó và tính chắc chắn của tính toàn vẹn tham chiếu.


1
Thật. Tôi nên nói rằng hiệu suất kiểm tra ràng buộc sẽ được xử lý tốt hơn trong cơ sở dữ liệu so với trong ứng dụng.
Kirk Broadhurst

13
  • Chúng ta không còn sống trong một thế giới phía sau <-> một thế giới phía trước.
  • Hầu hết các giải pháp liên quan đến giao diện người dùng web, giao diện người dùng di động, giao diện người dùng hàng loạt và giao diện người dùng iPad, v.v.
  • Các công cụ cơ sở dữ liệu đã có hàng ngàn dòng mã được thử nghiệm được tối ưu hóa để thực thi tính toàn vẹn tham chiếu.

Bạn có thể thực sự đủ khả năng viết và kiểm tra mã thực thi toàn vẹn tham chiếu khi bạn có mã giải quyết vấn đề tên miền để viết không?


2
"Chúng tôi không còn sống trong một thế giới phía sau <-> một thế giới phía trước." Chúng ta đã bao giờ? Vài năm trước, tôi đã làm việc trên một hệ thống cơ sở dữ liệu có các chương trình được viết bằng ít nhất hai chục ngôn ngữ khác nhau truy cập vào nó. Một số chương trình đã được phát hành đầu tiên vào những năm 1970.
Mike Sherrill 'Nhớ lại mèo'

2

Nếu bạn không xác thực tính toàn vẹn dữ liệu, các ràng buộc, các mối quan hệ, v.v. ở cấp cơ sở dữ liệu, điều đó có nghĩa là mọi người có quyền truy cập cơ sở dữ liệu sản xuất (thông qua bất kỳ ứng dụng khách nào khác bao gồm cả công cụ truy cập DB) sẽ làm rối dữ liệu của bạn.

Đó là một thực tiễn tuyệt vời để thực thi tính toàn vẹn dữ liệu nghiêm ngặt nhất có thể ở cấp cơ sở dữ liệu. Tin tôi đi, điều này sẽ giúp bạn tiết kiệm được những cơn đau đầu khủng khiếp theo thời gian trong bất kỳ hệ thống không tầm thường nào. Bạn cũng sẽ nhận các lỗi logic ứng dụng hoặc lỗi yêu cầu nghiệp vụ và sự không nhất quán nhanh hơn nếu suy nghĩ cẩn thận được đưa vào đây.

Như một lưu ý phụ cho điều này, hãy thiết kế cơ sở dữ liệu của bạn theo cách bình thường hóa và nguyên tử nhất có thể. Không có bảng "Chúa". Dành nhiều nỗ lực để thiết kế cơ sở dữ liệu của bạn đơn giản nhất có thể, lý tưởng với nhiều bảng nhỏ được xác định rất rõ ràng, với một trách nhiệm duy nhất và được xác thực cẩn thận trên tất cả các cột. Cơ sở dữ liệu là người bảo vệ cuối cùng của tính toàn vẹn dữ liệu của bạn. Nó đại diện cho Keep of the Castle.


1

Hầu hết mọi người về cơ bản đều nói "vâng, nói chung, bạn sẽ luôn xác định các mối quan hệ trong cơ sở dữ liệu". Nhưng nếu các ngành khoa học máy tính quá dễ dàng, chúng ta sẽ được gọi là "Trình đọc hướng dẫn phần mềm" thay vì "Kỹ sư phần mềm". Tôi thực sự đồng ý rằng các ràng buộc nên có trong cơ sở dữ liệu, trừ khi có lý do chính đáng mà họ không nên , vì vậy hãy để tôi cung cấp một vài lý do có thể được coi là tốt trong một số tình huống:

Mã trùng lặp

Đôi khi một lượng chức năng nhất định có thể được xử lý bởi cơ sở dữ liệu sẽ tự nhiên tồn tại trong mã ứng dụng. Nếu việc thêm một cái gì đó như các ràng buộc vào cơ sở dữ liệu sẽ là dư thừa, tốt hơn hết là không nên sao chép chức năng, vì bạn đang vi phạm các nguyên tắc DRY và bạn có thể làm xấu đi hành động tung hứng của việc giữ đồng bộ hóa cơ sở dữ liệu và mã ứng dụng.

Cố gắng

Nếu cơ sở dữ liệu của bạn đang làm những gì nó cần làm mà không cần sử dụng các tính năng nâng cao, bạn có thể muốn đánh giá thời gian, tiền bạc và công sức của mình nên được đặt ở đâu. Nếu thêm các ràng buộc sẽ ngăn chặn một thất bại thảm hại và do đó tiết kiệm cho công ty của bạn rất nhiều tiền, thì có lẽ nó đáng giá. Nếu bạn đang thêm các ràng buộc nên giữ, nhưng đã được đảm bảo không bao giờ bị vi phạm, bạn đang lãng phí thời gian và làm ô nhiễm cơ sở mã của mình. Đảm bảo là từ hoạt động ở đây.

Hiệu quả

Điều này thường không phải là một lý do tốt nhưng trong một số trường hợp bạn có thể có một yêu cầu hiệu suất nhất định. Nếu mã ứng dụng có thể triển khai một chức năng nhất định theo cách nhanh hơn cơ sở dữ liệu và bạn cần hiệu năng bổ sung, bạn có thể cần triển khai tính năng này trong mã ứng dụng.

Điều khiển

Hơi liên quan đến hiệu quả. Đôi khi bạn cần kiểm soát chi tiết cực kỳ tốt về cách triển khai một tính năng và đôi khi có cơ sở dữ liệu xử lý nó ẩn nó sau một hộp đen mà bạn cần mở.

Điểm đóng cửa

  • Cơ sở dữ liệu được viết bằng mã. Không có gì kỳ diệu họ làm mà bạn không thể làm trong mã của riêng bạn.
  • Không có gì miễn phí. Các ràng buộc, quan hệ, vv tất cả đều sử dụng chu kỳ CPU.
  • Mọi người trong thế giới NoQuery rất hợp nhau khi không có các tính năng Quan hệ truyền thống. Ví dụ, trong MongoDB, cấu trúc của các tài liệu JSON đủ tốt để hỗ trợ toàn bộ cơ sở dữ liệu.
  • Việc sử dụng mù quáng và thiếu hiểu biết về các tính năng cơ sở dữ liệu nâng cao không thể đảm bảo bất kỳ lợi ích nào. Bạn có thể vô tình làm một cái gì đó hoạt động chỉ để phá vỡ nó sau này.
  • Bạn đã hỏi một câu hỏi rất chung chung mà không liệt kê các yêu cầu cụ thể hoặc các ràng buộc. Câu trả lời thực sự cho câu hỏi của bạn là "nó phụ thuộc".
  • Bạn đã không xác định nếu đây là một vấn đề quy mô doanh nghiệp. Các câu trả lời khác đang nói về những thứ như khách hàng và tính toàn vẹn dữ liệu, nhưng đôi khi những điều đó không quan trọng.
  • Tôi giả sử bạn đang nói về một cơ sở dữ liệu quan hệ SQL truyền thống.
  • Quan điểm của tôi xuất phát từ việc chuyển sang sử dụng hàng tấn ràng buộc và khóa ngoại trong các dự án nhỏ (tối đa 50 bảng) và không nhận thấy bất kỳ nhược điểm nào .

Điều cuối cùng tôi sẽ nói là bạn sẽ biết nếu bạn không nên đặt chức năng trong cơ sở dữ liệu. Nếu bạn không chắc chắn, có lẽ bạn nên sử dụng các tính năng cơ sở dữ liệu, vì chúng thường hoạt động rất tốt.


1
Nếu mọi người hạ thấp câu trả lời được suy nghĩ kỹ vì nó không đồng ý với giáo điều của họ, SE StackExchange trở thành một nơi tồi tệ hơn.
Carl Leth

5
Câu trả lời này là tiền đề rằng có những lúc bạn có thể bỏ các ràng buộc ra khỏi DB là hợp lệ, nhưng lời giải thích là kém và sai. Mặc dù tôi đồng tình rằng cơ sở dữ liệu không phải là nơi tốt nhất cho một số ràng buộc, nhưng không có cơ sở dữ liệu quan hệ nào nên không có các ràng buộc toàn vẹn khóa và tham chiếu cơ bản . Không có . Không có ngoại lệ cho điều này. Mọi cơ sở dữ liệu sẽ cần khóa chính và đại đa số sẽ cần khóa ngoại. Chúng phải luôn được cơ sở dữ liệu thực thi, ngay cả khi nó trùng lặp logic. Thực tế là bạn bóng bẩy về điều này là lý do tại sao tôi đánh giá thấp.
jpmc26

1
"Cơ sở dữ liệu được viết bằng mã. Không có phép thuật nào họ làm mà bạn không thể làm trong mã của riêng mình." , không, bạn không thể thực thi tính toàn vẹn tham chiếu trong mã ứng dụng (và nếu bạn không cần phải thực thi nó, tại sao bạn lại sử dụng máy chủ cơ sở dữ liệu?). Đó không phải là về những gì mã có thể làm, mà là về nơi nó có thể được thực hiện.
hyde

0

Như mọi khi, có rất nhiều câu trả lời. Đối với tôi, tôi đã tìm thấy một quy tắc đơn giản (cũng chỉ hoạt động đối với cách tiếp cận lấy mô hình làm trung tâm). Thông thường, tôi chỉ tập trung vào các lớp ứng dụng khác nhau.

Nếu mô hình bao gồm một số thực thể và có các phụ thuộc giữa các thực thể, lớp kiên trì sẽ phản ánh các phụ thuộc đó với các khả năng của nó. Vì vậy, nếu bạn đang sử dụng RDBMS, thì bạn cũng nên sử dụng khóa ngoại. Lý do rất đơn giản. Bằng cách đó, dữ liệu luôn có cấu trúc hợp lệ.

Bất kỳ trường hợp nào làm việc trên lớp kiên trì này đều có thể dựa vào nó. Tôi giả sử rằng bạn đang đóng gói lớp này thông qua giao diện (dịch vụ). Vì vậy, đây là điểm mà thiết kế kết thúc và thế giới thực bắt đầu.

Nhìn vào điểm của bạn, đặc biệt là tài liệu tham khảo cơ sở dữ liệu chéo . Trong trường hợp đó, có, không nên có một tham chiếu được triển khai trong chính RDBMS, mà trong dịch vụ. Nhưng trước khi làm theo cách này, sẽ tốt hơn nếu xem xét điều này đã có trong quá trình thiết kế?

Có nghĩa là, nếu tôi đã biết, có những phần cần được lưu trữ trong một DB khác, thì tôi có thể đặt chúng ở đó và định nghĩa nó là mô hình riêng biệt. Đúng?

Bạn cũng chỉ ra rằng việc thực hiện điều này trong mã linh hoạt hơn . Phải, nhưng không có vẻ như bạn đang xử lý một thiết kế không hoàn chỉnh? Hãy tự hỏi, tại sao bạn cần linh hoạt hơn?

Vấn đề về hiệu năng, do kiểm tra tính toàn vẹn trong DB là không có thực. RDBMS có thể kiểm tra những thứ như vậy nhanh hơn nhiều so với bất kỳ triển khai nào của bạn. Tại sao? Chà, bạn phải đối phó với sự gián đoạn truyền thông, RDBMS thì không. Và nó có thể tối ưu hóa các kiểm tra như vậy bằng cách sử dụng số liệu thống kê của nó

Vì vậy, bạn thấy, tất cả trở lại với thiết kế. Tất nhiên bạn có thể nói bây giờ, nhưng nếu một yêu cầu không xác định xuất hiện, một người thay đổi trò chơi thì sao? Vâng, nó có thể xảy ra, nhưng những thay đổi như vậy nên được thiết kế và lên kế hoạch. ; o)


0

Bạn có một số câu trả lời rất tốt nhưng một số điểm nữa

Toàn vẹn dữ liệu là những gì một cơ sở dữ liệu được thiết kế để làm

Thực hiện đồng thời thích hợp như xóa FK ở cấp ứng dụng sẽ rất tệ

Chuyên môn về tính toàn vẹn dữ liệu là với một DBA

Ở cấp độ chương trình bạn chèn, cập nhật, cập nhật hàng loạt, chèn hàng loạt, xóa hàng loạt ...
Máy khách mỏng, máy khách dày, máy khách di động ....
Tính toàn vẹn dữ liệu không phải là chuyên môn của lập trình viên - rất nhiều mã trùng lặp và ai đó sẽ gây rối nó lên

Giả sử bạn bị hack - dù sao bạn cũng gặp rắc rối nhưng một hacker có thể gây ra nhiều thiệt hại thông qua một lỗ nhỏ nếu không có sự bảo vệ toàn vẹn tại cơ sở dữ liệu

Bạn có thể cần thao tác dữ liệu trực tiếp qua SQL hoặc TSQL
Không ai sẽ nhớ tất cả các quy tắc dữ liệu


0

Câu hỏi của bạn không có ý nghĩa: nếu bạn có thể thay đổi cơ sở dữ liệu, đó là mã, nếu bạn không thể thay đổi cơ sở dữ liệu, bạn sẽ phải tạo các ràng buộc của mình ở nơi khác.

Một cơ sở dữ liệu mà bạn có thể thay đổi là mỗi bit có nhiều mã như bất kỳ dòng ruby, javascript, c # hoặc ada nào.

Câu hỏi về nơi đặt một ràng buộc trong hệ thống của bạn sẽ làm giảm độ tin cậy, chi phí và dễ dàng phát triển.


0

Có rất nhiều câu trả lời hay ở đây. Tôi sẽ nói thêm rằng nếu bạn có một ứng dụng được viết bằng ngôn ngữ Y, bạn có thể tạo mã giống như cơ sở dữ liệu trong Y. Và sau đó ai đó muốn truy cập cơ sở dữ liệu của bạn bằng ngôn ngữ Z, bạn sẽ phải viết lại mã đó. Chúa sẽ giúp bạn nếu việc triển khai không hoàn toàn giống nhau. Hoặc khi người dùng doanh nghiệp có kiến ​​thức kết nối với cơ sở dữ liệu của bạn bằng Microsoft Access.

Kinh nghiệm của tôi cho tôi biết rằng khi mọi người không muốn sử dụng các ràng buộc cơ sở dữ liệu, thì đó là vì họ thực sự đang cố làm sai điều gì đó. Ví dụ: họ đang cố gắng tải dữ liệu hàng loạt và họ muốn để các cột không null trong một thời gian. Họ dự định sẽ "khắc phục điều đó sau" bởi vì tình huống khiến cho ràng buộc không có giá trị nghiêm trọng "không thể xảy ra trong trường hợp này". Một ví dụ khác có thể là khi họ cố gắng cắm sừng hai loại dữ liệu khác nhau vào cùng một bảng.

Những người có kinh nghiệm hơn sẽ lùi lại một bước và tìm ra giải pháp không liên quan đến việc cố gắng vượt qua một ràng buộc. Giải pháp đơn giản có thể là sự hạn chế không còn phù hợp vì doanh nghiệp đã thay đổi, tất nhiên.

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.