Logic nghiệp vụ trong cơ sở dữ liệu bằng SchemaKeeper

Mục đích của bài viết này là sử dụng ví dụ về một thư viện người giữ lược đồ hiển thị các công cụ có thể đơn giản hóa đáng kể quá trình phát triển cơ sở dữ liệu trong các dự án PHP bằng cách sử dụng DBMS PostgreSQL.

Thông tin từ bài viết này trước hết sẽ hữu ích cho các nhà phát triển muốn tận dụng tối đa khả năng của PostgreSQL nhưng đang gặp phải vấn đề duy trì logic nghiệp vụ được đặt trong cơ sở dữ liệu.

Bài viết này sẽ không mô tả những ưu điểm hay nhược điểm của việc lưu trữ logic nghiệp vụ trong cơ sở dữ liệu. Người ta cho rằng sự lựa chọn đã được người đọc đưa ra.

Các câu hỏi sau đây sẽ được xem xét:

  1. Kết xuất cấu trúc cơ sở dữ liệu nên được lưu trữ ở dạng nào trong hệ thống kiểm soát phiên bản (sau đây gọi là VCS)
  2. Cách theo dõi các thay đổi trong cấu trúc cơ sở dữ liệu sau khi lưu kết xuất
  3. Cách chuyển các thay đổi trong cấu trúc cơ sở dữ liệu sang môi trường khác mà không bị xung đột và các tệp di chuyển khổng lồ
  4. Cách tổ chức quá trình làm việc song song trên một dự án của một số nhà phát triển
  5. Cách triển khai an toàn nhiều thay đổi hơn trong cấu trúc cơ sở dữ liệu sang môi trường sản xuất

    Trình giữ lược đồ được thiết kế để làm việc với các thủ tục lưu trữ được viết bằng ngôn ngữ PL / pgSQL. Việc thử nghiệm với các ngôn ngữ khác chưa được thực hiện nên việc sử dụng có thể không hiệu quả hoặc có thể không thực hiện được.

Cách lưu trữ kết xuất cấu trúc cơ sở dữ liệu trong VCS

Thư viện người giữ lược đồ cung cấp một chức năng saveDump, lưu cấu trúc của tất cả các đối tượng từ cơ sở dữ liệu dưới dạng các tệp văn bản riêng biệt. Đầu ra là một thư mục chứa cấu trúc cơ sở dữ liệu, được chia thành các tệp được nhóm lại để có thể dễ dàng thêm vào VCS.

Hãy xem xét việc chuyển đổi các đối tượng từ cơ sở dữ liệu thành tệp bằng một số ví dụ:

Loại đối tượng
Đề án
tên
Đường dẫn tương đối tới tập tin

bàn
công khai
tài khoản
./public/tables/accounts.txt

Thủ tục lưu trữ
công khai
auth(băm bigint)
./public/functions/auth(int8).sql

Giới thiệu
đặt phòng
thuế quan
./booking/views/tariffs.txt

Nội dung của các tệp là sự thể hiện bằng văn bản về cấu trúc của một đối tượng cơ sở dữ liệu cụ thể. Ví dụ: đối với các thủ tục được lưu trữ, nội dung của tệp sẽ là định nghĩa đầy đủ của thủ tục được lưu trữ, bắt đầu bằng khối CREATE OR REPLACE FUNCTION.

Như có thể thấy từ bảng trên, đường dẫn đến tệp lưu trữ thông tin về loại, lược đồ và tên của đối tượng. Cách tiếp cận này giúp việc điều hướng qua kết xuất và xem xét mã về các thay đổi trong cơ sở dữ liệu trở nên dễ dàng hơn.

sự mở rộng .sql đối với các tệp có mã nguồn thủ tục được lưu trữ, mã này được chọn để IDE tự động cung cấp các công cụ tương tác với cơ sở dữ liệu khi tệp được mở.

Cách theo dõi các thay đổi trong cấu trúc cơ sở dữ liệu sau khi lưu kết xuất

Bằng cách lưu kết xuất cấu trúc cơ sở dữ liệu hiện tại trong VCS, chúng tôi có cơ hội kiểm tra xem các thay đổi có được thực hiện đối với cấu trúc cơ sở dữ liệu sau khi kết xuất được tạo hay không. Trong thư viện người giữ lược đồ để phát hiện những thay đổi trong cấu trúc cơ sở dữ liệu, một chức năng được cung cấp verifyDump, trả về thông tin về sự khác biệt mà không có tác dụng phụ.

Một cách khác để kiểm tra là gọi lại hàm saveDump, chỉ định cùng một thư mục và kiểm tra VCS để biết các thay đổi. Vì tất cả các đối tượng từ cơ sở dữ liệu được lưu trong các tệp riêng biệt nên VCS sẽ chỉ hiển thị các đối tượng đã thay đổi.
Nhược điểm chính của phương pháp này là cần phải ghi đè lên tệp để xem các thay đổi.

Cách chuyển các thay đổi trong cấu trúc cơ sở dữ liệu sang môi trường khác mà không bị xung đột và các tệp di chuyển khổng lồ

Nhờ chức năng deployDump Mã nguồn của các thủ tục lưu trữ có thể được chỉnh sửa theo cách giống hệt như mã nguồn ứng dụng thông thường. Bạn có thể thêm/xóa các dòng mới trong mã thủ tục được lưu trữ và ngay lập tức đẩy các thay đổi vào kiểm soát phiên bản hoặc tạo/xóa các thủ tục đã lưu trữ bằng cách tạo/xóa các tệp tương ứng trong thư mục kết xuất.

Ví dụ: để tạo một thủ tục lưu trữ mới trong lược đồ public chỉ cần tạo một tệp mới với phần mở rộng .sql trong thư mục public/functions, đặt mã nguồn của thủ tục được lưu trữ vào đó, bao gồm cả khối CREATE OR REPLACE FUNCTION, sau đó gọi hàm deployDump. Việc sửa đổi và xóa một thủ tục lưu sẵn cũng diễn ra theo cách tương tự. Do đó, mã đi vào cả VCS và cơ sở dữ liệu cùng một lúc.

Nếu có lỗi xuất hiện trong mã nguồn của bất kỳ thủ tục được lưu trữ nào hoặc có sự khác biệt giữa tên của tệp và thủ tục được lưu trữ thì deployDump sẽ thất bại, hiển thị văn bản lỗi. Không thể thực hiện được các thủ tục được lưu trữ giữa kết xuất và cơ sở dữ liệu hiện tại khi sử dụng deployDump.

Khi tạo một thủ tục lưu trữ mới, không cần phải nhập đúng tên tệp theo cách thủ công. Chỉ cần file có phần mở rộng là đủ .sql. Sau cuộc gọi deployDump văn bản lỗi sẽ chứa tên chính xác, tên này có thể được sử dụng để đổi tên tệp.

deployDump cho phép bạn thay đổi các tham số của hàm hoặc kiểu trả về mà không cần thực hiện thêm hành động nào, trong khi với cách tiếp cận cổ điển, bạn sẽ phải
thực hiện đầu tiên DROP FUNCTION, và chỉ sau đó CREATE OR REPLACE FUNCTION.

Thật không may, có một số tình huống mà deployDump không thể tự động áp dụng các thay đổi. Ví dụ: nếu chức năng kích hoạt được ít nhất một trình kích hoạt sử dụng bị loại bỏ. Những tình huống như vậy được giải quyết thủ công bằng cách sử dụng các tệp di chuyển.

Nếu bạn chịu trách nhiệm di chuyển các thay đổi sang các thủ tục được lưu trữ người giữ lược đồ, thì các tệp di chuyển phải được sử dụng để chuyển các thay đổi khác trong cấu trúc. Ví dụ: một thư viện tốt để làm việc với việc di chuyển là học thuyết/di cư.

Việc di chuyển phải được áp dụng trước khi khởi chạy deployDump. Điều này cho phép bạn thực hiện tất cả các thay đổi đối với cấu trúc và giải quyết các tình huống có vấn đề để các thay đổi trong thủ tục lưu trữ sau đó được chuyển đi mà không gặp vấn đề gì.

Làm việc với việc di chuyển sẽ được mô tả chi tiết hơn trong các phần sau.

Cách tổ chức quá trình làm việc song song trên một dự án của một số nhà phát triển

Cần phải tạo một tập lệnh để khởi tạo hoàn chỉnh cơ sở dữ liệu, tập lệnh này sẽ được nhà phát triển khởi chạy trên máy làm việc của mình, đưa cấu trúc của cơ sở dữ liệu cục bộ phù hợp với kết xuất được lưu trong VCS. Cách dễ nhất là chia việc khởi tạo cơ sở dữ liệu cục bộ thành 3 bước:

  1. Nhập tệp có cấu trúc cơ bản sẽ được gọi là ví dụ: base.sql
  2. Áp dụng di chuyển
  3. Gọi deployDump

base.sql là điểm bắt đầu mà việc di chuyển được áp dụng và thực thi deployDumpĐó là, base.sql + миграции + deployDump = актуальная структура БД. Bạn có thể tạo một tệp như vậy bằng tiện ích pg_dump. Đã sử dụng base.sql riêng khi khởi tạo cơ sở dữ liệu từ đầu.

Hãy gọi tập lệnh để khởi tạo cơ sở dữ liệu hoàn chỉnh refresh.sh. Quy trình làm việc có thể trông như thế này:

  1. Nhà phát triển khởi chạy trong môi trường của mình refresh.sh và lấy cấu trúc cơ sở dữ liệu hiện tại
  2. Nhà phát triển bắt đầu thực hiện nhiệm vụ hiện tại, sửa đổi cơ sở dữ liệu cục bộ để đáp ứng nhu cầu của chức năng mới (ALTER TABLE ... ADD COLUMN vân vân)
  3. Sau khi hoàn thành nhiệm vụ, nhà phát triển gọi hàm saveDumpđể cam kết các thay đổi được thực hiện đối với cơ sở dữ liệu trong VCS
  4. Nhà phát triển khởi chạy lại refresh.sh, sau đó verifyDumphiện hiển thị danh sách các thay đổi cần đưa vào quá trình di chuyển
  5. Nhà phát triển chuyển tất cả các thay đổi cấu trúc sang tệp di chuyển, chạy lại refresh.sh и verifyDumpvà nếu quá trình di chuyển được biên dịch chính xác, verifyDump sẽ không hiển thị sự khác biệt giữa cơ sở dữ liệu cục bộ và kết xuất đã lưu

Quá trình được mô tả ở trên tương thích với các nguyên tắc của gitflow. Mỗi nhánh trong VCS sẽ chứa phiên bản kết xuất riêng của nó và khi hợp nhất các nhánh, các kết xuất sẽ được hợp nhất. Trong hầu hết các trường hợp, không cần thực hiện hành động bổ sung nào sau khi hợp nhất, nhưng nếu các thay đổi được thực hiện ở các nhánh khác nhau, chẳng hạn như đối với cùng một bảng, thì xung đột có thể phát sinh.

Hãy xem xét một tình huống xung đột bằng một ví dụ: có một nhánh phát triển, từ đó có hai nhánh phân nhánh: tính năng1 и tính năng2, không có xung đột với phát triểnnhưng lại có xung đột với nhau. Nhiệm vụ là hợp nhất cả hai nhánh thành phát triển. Trong trường hợp này, trước tiên nên hợp nhất một trong các nhánh thành phát triểnrồi hợp nhất phát triển tới nhánh còn lại, giải quyết xung đột ở nhánh còn lại và sau đó sáp nhập nhánh cuối cùng vào phát triển. Trong giai đoạn giải quyết xung đột, bạn có thể phải sửa tệp di chuyển ở nhánh cuối cùng để nó khớp với kết xuất cuối cùng, bao gồm kết quả của việc hợp nhất.

Cách triển khai an toàn nhiều thay đổi hơn trong cấu trúc cơ sở dữ liệu sang môi trường sản xuất

Nhờ sự hiện diện của kết xuất cấu trúc cơ sở dữ liệu hiện tại trong VCS, có thể kiểm tra cơ sở dữ liệu sản xuất xem có tuân thủ chính xác cấu trúc được yêu cầu hay không. Điều này đảm bảo rằng tất cả những thay đổi mà nhà phát triển dự định đã được chuyển thành công sang cơ sở sản xuất.

Như DDL trong PostgreSQL là giao dịch, bạn nên tuân thủ trình tự triển khai sau để trong trường hợp xảy ra lỗi không mong muốn, bạn có thể thực thi “một cách dễ dàng” ROLLBACK:

  1. Bắt đầu giao dịch
  2. Thực hiện tất cả các di chuyển trong một giao dịch
  3. Trong cùng một giao dịch, thực hiện deployDump
  4. Không hoàn thành giao dịch, hãy thực hiện verifyDump. Nếu không có lỗi thì chạy COMMIT. Nếu có lỗi thì chạy ROLLBACK

Các bước này có thể được tích hợp khá dễ dàng vào các phương pháp hiện có để triển khai ứng dụng, bao gồm cả thời gian ngừng hoạt động bằng không.

Kết luận

Nhờ các phương pháp được mô tả ở trên, có thể đạt được hiệu suất tối đa từ các dự án “PHP + PostgreSQL”, đồng thời hy sinh tương đối ít sự tiện lợi khi phát triển so với việc triển khai tất cả logic nghiệp vụ trong mã ứng dụng chính. Hơn nữa, việc xử lý dữ liệu trong PL / pgSQL thường trông minh bạch hơn và yêu cầu ít mã hơn so với chức năng tương tự được viết bằng PHP.

Nguồn: www.habr.com

Thêm một lời nhận xét