Cơ sở dữ liệu quan hệ và phát triển lặp


19

Trong nhiều cách tiếp cận để phát triển phần mềm như các phương pháp nhanh, Thiết kế và phân tích hướng đối tượng và thiết kế hướng đối tượng, chúng tôi được khuyến khích thực hiện một cách tiếp cận lặp lại để phát triển.

Vì vậy, chúng tôi không được phép thực hiện mô hình miền của mình ngay lần đầu tiên chúng tôi bắt đầu làm việc trong dự án. Thay vào đó, khi thời gian trôi qua, chúng ta tái cấu trúc mô hình bởi vì chúng ta hiểu sâu hơn về miền vấn đề theo thời gian.

Ngoài ra, ngay cả khi chúng tôi cố gắng để có được một mô hình hoàn hảo, điều mà tôi đã bị thuyết phục là rất khó, các yêu cầu có thể thay đổi. Vì vậy, sau khi phần mềm đã được triển khai để sản xuất, người dùng cuối có thể nhận thấy rằng một yêu cầu nhất định không được hiểu hoàn toàn, hoặc tệ hơn, một số yêu cầu bị thiếu.

Vấn đề ở đây là chúng ta có thể cần phải thay đổi mô hình sau khi phần mềm đã được triển khai. Nếu điều này xảy ra, chúng tôi có một vấn đề: cơ sở dữ liệu sản xuất có dữ liệu của người dùng rất quan trọng và đã được trang bị định dạng cho mẫu cũ .

Cập nhật mã có thể là một nhiệm vụ khó khăn nếu mã không được thiết kế tốt và nếu hệ thống lớn. Nhưng nó có thể được thực hiện với thời gian, chúng tôi có các công cụ như Git giúp chúng tôi làm điều đó mà không làm hỏng phiên bản sẵn sàng sản xuất.

Mặt khác, nếu mô hình thay đổi, nếu các thuộc tính của các lớp biến mất hoặc bất cứ điều gì, cơ sở dữ liệu cũng sẽ thay đổi. Nhưng chúng tôi có một vấn đề: đã có dữ liệu ở đó không thể bị mất, dữ liệu đã được hình thành cho mô hình cũ.

Dường như một cơ sở dữ liệu quan hệ ở đây đang là rào cản ngăn chúng tôi thực hiện phát triển lặp và thậm chí cập nhật phần mềm khi người dùng cuối yêu cầu.

Một cách tiếp cận tôi đã sử dụng là mã hóa một lớp đặc biệt ánh xạ các bảng cơ sở dữ liệu cũ sang các bảng mới. Vì vậy, các lớp này chọn dữ liệu ở định dạng cũ, chuyển đổi nó sang định dạng được sử dụng bởi mô hình mới và lưu vào các bảng mới.

Cách tiếp cận này dường như không phải là cách tốt nhất. Câu hỏi của tôi ở đây là: có bất kỳ cách tiếp cận nổi tiếng và được đề xuất nào để điều hòa sự phát triển lặp lại với cơ sở dữ liệu quan hệ không?


6
Ngẫu nhiên, tôi không nghĩ rằng điều này có liên quan đến cơ sở dữ liệu quan hệ nói riêng. Tôi có một vấn đề tương tự với một dự án tôi đang thực hiện, nhưng chúng tôi đang có nó với lược đồ cho các chuỗi JSON của chúng tôi đại diện cho các đối tượng không liên quan. Nó có thể ảnh hưởng đến tất cả các hình thức kiên trì như nhau.
Ixrec

1
Bạn thay đổi lược đồ cơ sở dữ liệu theo cách không mất dữ liệu, en.wikipedia.org/wiki/Schema_migration .
RemcoGerlich

1
Tôi chắc chắn chủ đề này đã được thảo luận rộng rãi ở đâu đó trước đây, nhưng không thể tìm thấy nó trên Lập trình viên. Nhưng hãy xem tại đây martinfowler.com/articles/evodb.html hoặc tại đây stackoverflow.com/questions/334059/
Doc Brown

1
"Ngoài ra, ngay cả khi chúng tôi cố gắng để có được một mô hình hoàn hảo, điều mà tôi đã bị thuyết phục là rất khó, các yêu cầu có thể thay đổi." Tôi muốn nói thêm rằng bạn thậm chí không nên cố gắng đưa một mô hình (gần hoàn hảo) lên phía trước. Điều đó có thể buộc suy nghĩ của bạn xuống một loại giải pháp thay vì giữ cho các tùy chọn của bạn mở.
Bent

Câu trả lời:


15

Nó không phải là các lớp đặc biệt, nhưng vâng, bạn cần một cái gì đó sẽ lấy cơ sở dữ liệu ở định dạng trước đó và chuyển đổi nó thành lớp hiện tại.

Vấn đề ở đây là bạn cần phát triển một quy trình viết và kiểm tra các tập lệnh và kỷ luật này để không bao giờ chạm vào cơ sở dữ liệu kiểm thử và sản xuất, mà luôn luôn bằng các tập lệnh di chuyển.

Mỗi khi bạn cần thay đổi cơ sở dữ liệu, bạn viết một tập lệnh sẽ thực hiện nó, cho dù bằng SQL hoặc sử dụng lớp ORM của bạn và cam kết nó với điều khiển phiên bản của bạn cùng với các thay đổi yêu cầu lược đồ mới. Sau đó, bạn có một số tập lệnh kiểm soát sẽ nâng cấp cơ sở dữ liệu bằng cách áp dụng tất cả các tập lệnh di chuyển chưa được áp dụng theo trình tự.

Và hãy chắc chắn rằng bạn chỉ sửa đổi bất kỳ môi trường phát triển, kiểm tra và QA được chia sẻ nào bằng cách áp dụng các tập lệnh và quay lại phiên bản trước nếu chúng không hoạt động, vì vậy bạn có thể tin tưởng một cách hợp lý rằng chúng sẽ hoạt động như dự định khi bạn giải phóng chúng .

Cài đặt mới được thực hiện đơn giản bằng cách áp dụng tất cả các tập lệnh. Sau một thời gian, bạn có thể có hàng trăm người trong số họ và nghĩ rằng nó rất kém hiệu quả, nhưng đừng rơi vào cái bẫy cố gắng tối ưu hóa nó. Cài đặt là một hoạt động một lần và giữ cho nó đáng tin cậy làm cho nó nhanh chóng.

@Doc Brown đã liên kết Martin Fowler: Thiết kế cơ sở dữ liệu tiến hóa/programming/334059/agile-development-and-database-changes và tôi sẽ thêm Alex Papadimoulis: Thay đổi cơ sở dữ liệu được thực hiện đúng , ngắn hơn và có một số ví dụ.

Như một ví dụ điển hình về công cụ thực hiện quy trình như vậy, tôi đề nghị Alembic . Nó dựa trên khung SQLAlAlemy của Python , nhưng bạn có thể sử dụng nó với các ngôn ngữ và khung khác nếu chúng không có hỗ trợ di chuyển riêng. Trang Wikipedia về Schema Migration liệt kê thêm các công cụ như vậy .


1
@Tibo bạn xây dựng lược đồ từ đầu bằng cách chạy cùng một chuỗi các kịch bản. Đó là cách bạn quản lý vấn đề. Cho rằng đó là một tiêu chuẩn mà bạn có thể nhận được từ bất kỳ trường hợp nào của cơ sở dữ liệu - bao gồm cả một cơ sở dữ liệu chưa tồn tại - cho một lược đồ hiện tại và tin tưởng rằng nó giống nhau. Không cần phải có hai cách theo ví dụ của bạn. (Ít nhất là không đưa ra một đường cơ sở nhất quán - bước đầu tiên là thiết lập đường cơ sở và một khi bạn đạt được đường cơ sở đó, vấn đề sẽ biến mất.)
Murph

1
Đồng ý với bài viết của Alex; nó có thể không ngắn hơn, nhưng nó làm cho việc đọc hướng đến thực hành và giải trí nhiều hơn.
Murphy

1
Chúng tôi là một cửa hàng Agile và chúng tôi điều hành dịch vụ 100% thời gian hoạt động và cả hai đều áp dụng cho DB. Chúng tôi di chuyển lược đồ sản xuất trung bình mỗi ngày một lần và tôi sẽ thứ hai mọi thứ mà Jan đã nói. Một điều nữa chúng tôi làm đó là vô giá là cái mà chúng tôi gọi là thử nghiệm di chuyển, đây là một phần của quá trình xây dựng và triển khai của chúng tôi. Nó lấy một lược đồ chụp nhanh sản xuất, áp dụng bất kỳ chuyển đổi đang chờ xử lý nào từ chủ sang nó và sau đó chạy thử nghiệm đơn vị từ mã sản xuất hiện đang triển khai đối với lược đồ đó. Mục tiêu là để kiểm tra xem việc áp dụng di chuyển sẽ không phá vỡ hệ thống đang chạy.
Gordon Wrigley

1

Thật kỳ lạ, đây là vấn đề rất lớn đối với đội ngũ phát triển hiện tại của tôi. Câu hỏi có chứa một số câu hỏi phụ, vì vậy chúng sẽ được giải quyết độc lập.

Trước hết, một cơ sở dữ liệu quan hệ có ràng buộc mô hình dữ liệu quá nhiều, làm cho các thay đổi rất khó khăn?

Chắc chắn nhất , nhưng không nhất thiết vì những lý do được trích dẫn. Thật không may, tính linh hoạt của các hệ thống quản lý cơ sở dữ liệu quan hệ cũng dẫn đến sự sụp đổ của chúng. RDBMS ban đầu được phát triển để cung cấp một nền tảng lưu trữ dữ liệu tương đối đơn giản, có thể chấp nhận các tập dữ liệu lớn và giảm chúng xuống kích thước tương đối nhỏ. Điều này đã được thực hiện với chi phí phức tạp trong mô hình dữ liệu và sức mạnh tính toán cần thiết. Khi độ phức tạp của cơ sở dữ liệu tăng lên, các thủ tục được lưu trữ, các khung nhìn, các hàm và các trình kích hoạt ra đời để giúp các quản trị viên cơ sở dữ liệu giải quyết sự phức tạp một cách nhất quán và có thể mở rộng.

Thật không may, mô hình cơ sở dữ liệu quan hệ không hướng đối tượng và không tự nhiên ánh xạ tới các thực thể trong thế giới thực như một mô hình dữ liệu nên. Điều đó dẫn chúng ta đến nhu cầu về các công cụ trung gian như người lập bản đồ quan hệ đối tượng và những thứ tương tự. Thật không may, trong khi các công cụ này rõ ràng có một vị trí trong thế giới phát triển ngày nay, việc sử dụng chúng chỉ nhắm vào một triệu chứng của vấn đề phức tạp dữ liệu quan hệ, chứ không phải là nguyên nhân cơ bản, đó là sự sai lệch của mô hình dữ liệu với thế giới thực.

Điều đó dẫn đến phần thứ hai của câu hỏi, đây thực sự là một giả định, nhưng nên được xem như một câu hỏi: chúng ta có nên thực hiện mô hình miền của mình ngay lần đầu tiên không?

Vâng, đến một mức độ. Như câu hỏi đã chỉ ra, hiếm khi có thể hiểu đầy đủ vấn đề khi chúng ta bắt đầu quá trình thiết kế. Tuy nhiên, sự khác biệt giữa một mô hình dữ liệu hoàn toàn không chính xác, trái ngược với mô hình dữ liệu có thể được điều chỉnh khi chúng ta hiểu rõ hơn về miền, là mô hình ánh xạ kết hợp với thế giới thực. Điều này có nghĩa là chúng ta phải nỗ lực để tạo ra một mô hình dữ liệu ban đầu phù hợp với sự hiểu biết của chúng ta về vấn đề này theo các thực thể trong thế giới thực của nó. Nếu chúng ta bắt đầu bình thường hóa trên các thực thể sai, mô hình dữ liệu sẽ sai theo hai cách và việc khôi phục sẽ khó khăn.

Theo nhiều cách, việc chuyển sang các giải pháp cơ sở dữ liệu "Không SQL" là kết quả của các vấn đề về sự không phù hợp của mô hình dữ liệu. Sử dụng một cách tiếp cận hướng đối tượng Không có cách tiếp cận SQL nào khiến chúng ta phải suy nghĩ nhiều hơn về ánh xạ giữa các đối tượng trong mã và các đối tượng trong thế giới thực - và khi chúng ta gặp phải sự không nhất quán, nó thường không thể thực hiện được vì nó không thể thực hiện được trong chúng ta cơ sở dữ liệu. Điều này dẫn đến thiết kế tổng thể tốt hơn.

Điều đó dẫn đến câu hỏi cuối cùng: là một mô hình dữ liệu quan hệ không phù hợp với cách tiếp cận nhanh?

Không, nhưng cần nhiều kỹ năng hơn. Trong khi trong thế giới No-SQL, việc thêm một trường hoặc chuyển đổi một thuộc tính thành một mảng là không quan trọng, thì việc làm những điều này trong thế giới quan hệ là không quan trọng. Ở mức tối thiểu, một người có khả năng hiểu cả mô hình dữ liệu quan hệ và các thực thể trong thế giới thực mà họ đại diện. Người này là cá nhân sẽ tạo điều kiện cập nhật mô hình quan hệ khi sự hiểu biết về mô hình thế giới thực thay đổi. Không có viên đạn bạc để giải quyết vấn đề này.


1
Tôi thực sự hy vọng bạn quá khổ một vấn đề tạo ra một trường mới trong bảng RDBMS để làm cho tuyên bố trở nên kịch tính hơn. Bảng cơ sở dữ liệu cần phải rất đặc biệt (hoặc loại trường mới cần phải là một cái gì đó đặc biệt) để thực sự tạo ra một vấn đề để thêm một trường.
Alexey Zimarev

Phải, nhưng nó không bao giờ chỉ là một lĩnh vực ...
Người chơi

1
Tôi sẽ nói thường xuyên hơn nó chỉ là một lĩnh vực. Thay đổi lược đồ kịch không thường xuyên. Tôi không phải là người thích sử dụng RDBMS với thiết kế OO do không khớp trở kháng. Tuy nhiên, việc thêm các loại (bảng) và thuộc tính (cột) mới tương đối dễ dàng trong cả hai thế giới mặc dù trong NoQuery thực sự dễ dàng hơn một chút. Nhưng thay đổi phức tạp là đau trong cả hai trường hợp. Tệ hơn nữa là nó trở thành một hệ thống có nguồn gốc với các ảnh chụp nhanh, ngược lại với trải nghiệm phát triển cho hệ thống đó thú vị như thế nào.
Alexey Zimarev

Tôi thấy rằng các cơ sở dữ liệu quan hệ thường được sử dụng như "cái búa vạn năng" để giải quyết nhu cầu lưu trữ dữ liệu - trong khi thực tế có những lý do rất cụ thể để sử dụng chúng. Trong một hệ thống được cân nhắc kỹ lưỡng, người ta hiếm khi phải lo lắng về các vấn đề tôi đã viết trong câu trả lời của mình - Tôi đang giải quyết ở một đối tượng chung hơn, những người có thể không có kinh nghiệm để đến trước một thiết kế hệ thống phù hợp.
theMayer 29/2/2016

Không có sự khác biệt giữa mô hình quan hệ và nó thường ánh xạ tới thế giới thực cũng như bất kỳ loại mô hình nào khác. Một số hoạt động sẽ dễ dàng hơn với một loại và khác với loại khác. Vấn đề là khi bạn tạo một mô hình của một loại (hướng đối tượng) và cố gắng thực hiện nó với các công cụ thuộc loại khác (quan hệ). Điều đó không làm việc tốt. Nhưng thế giới thực không hướng đối tượng. Nó chỉ là và bạn mô hình hóa nó. Và phải sử dụng các công cụ phù hợp cho loại mô hình đã chọn.
Jan Hudec

-1

Điểm chính là không tái cấu trúc quá nhiều để mô hình của bạn thay đổi vượt quá mọi sự công nhận. Ngay cả với sự phát triển lặp đi lặp lại, bạn thực sự nên xây dựng dựa trên những thứ hiện có và không tái cấu trúc nó thành từng mảnh.

Điều này cung cấp cho bạn 2 tùy chọn chính để xử lý các thay đổi lớn khi chúng đến: đầu tiên là xây dựng lớp DB dưới dạng API, sử dụng các thủ tục được lưu trữ để chúng có thể được thay đổi cho phù hợp với máy khách mà không thay đổi lược đồ dữ liệu cơ bản.

Một cách khác là thay thế các bảng bằng một chút di chuyển dữ liệu. Khi cần thay đổi quy mô lớn, bạn tạo lược đồ mới và triển khai một tập các tập lệnh để lấy dữ liệu cũ và đưa nó vào định dạng mới. Nó tốn thời gian để làm điều này, đó là lý do tại sao bạn dựa nhiều hơn vào các phương pháp sửa đổi quyền truy cập dữ liệu rẻ hơn (ví dụ thông qua SP) làm lựa chọn đầu tiên.

Vì vậy: 1. cố gắng suy nghĩ trước với thiết kế để bạn không cần thay đổi mọi thứ.

  1. Dựa vào trình bao bọc hoặc API để thay đổi bị hạn chế hoặc có thể bị ẩn bên trong một thành phần bị cô lập

  2. Dành thời gian để nâng cấp đúng cách nếu bạn phải.

Các bước này áp dụng cho mọi thứ, không chỉ cơ sở dữ liệu.


Đề án cơ bản đôi khi cần phải được thay đổi. Khi ứng dụng bước vào thử nghiệm của khách hàng, các thuộc tính mới sẽ tăng lên mà bạn chưa bao giờ nghe thấy, các thuộc tính mà bạn nghĩ là các số hóa ra là các chuỗi, sau đó tất cả các mối quan hệ mà bạn mong đợi sẽ là 1: 1. Bạn không thể bao gồm những thứ này đằng sau các thủ tục được lưu trữ (bên cạnh đó, các thủ tục được lưu trữ là một phần của vấn đề, bởi vì, giống như những thứ khác trong cơ sở dữ liệu, chúng không nằm trong kiểm soát phiên bản).
Jan Hudec

@JanHudec từ khi nào SP không sống trong kiểm soát phiên bản? Bạn có thể bao gồm những thứ như vậy, bạn thay đổi API SP để lấy một chuỗi và viết nó sang một trường khác, xử lý các số cũ và chuỗi mới trong một chút mã trong SP của bạn. Không phải là tốt nhất, nhưng nó có thể tốt hơn là đi đến mọi trang web của khách hàng để di chuyển dữ liệu của họ sang định dạng chuỗi mới (có những ví dụ tốt hơn, nhưng bạn hiểu ý). Nếu thay đổi hóa ra là lớn, thì bạn phải di chuyển, nhưng ít nhất với API DB, bạn cũng có các tùy chọn khác, rẻ hơn.
gbjbaanb

Bạn vẫn phải đến từng trang web của khách hàng để cài đặt SP và thêm trường mới. Và khi bạn ở đó, bạn cũng có thể di chuyển dữ liệu. SP rất hữu ích ở chỗ chúng cho phép bạn tạo giao diện tương thích ngược nếu bạn có nhiều ứng dụng truy cập cơ sở dữ liệu, do đó bạn không phải nâng cấp tất cả chúng cùng một lúc. Nhưng họ không lưu bất kỳ bước nào khi lược đồ cần thay đổi do yêu cầu thay đổi.
Jan Hudec
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.