PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

chuỗi tạo postgresql không có khoảng cách

Các chuỗi không tạo ra các tập hợp số không có khoảng trống và thực sự không có cách nào để khiến chúng làm điều đó bởi vì quá trình khôi phục hoặc lỗi sẽ "sử dụng" số thứ tự.

Tôi đã viết một bài báo về điều này một thời gian trước đây. Nó hướng đến Oracle nhưng thực sự là về các nguyên tắc cơ bản của các con số không có khoảng cách và tôi nghĩ điều tương tự cũng áp dụng ở đây.

Chà, nó đã xảy ra một lần nữa. Ai đó đã hỏi làm thế nào để thực hiện một yêu cầu để tạo ra một chuỗi số không có khoảng cách và một loạt những người không nói gì đã hạ xuống họ để nói (và ở đây tôi diễn giải một chút) rằng điều này sẽ giết chết hiệu suất của hệ thống, đó là một yêu cầu hiếm khi hợp lệ. , rằng ai đã viết yêu cầu là một tên ngốc blah blah blah.

Như tôi đã chỉ ra trong chủ đề, đôi khi là một yêu cầu pháp lý thực sự để tạo ra các chuỗi số không có khoảng cách. Số hóa đơn cho hơn 2.000.000 tổ chức ở Vương quốc Anh đã đăng ký VAT (thuế bán hàng) có yêu cầu như vậy và lý do cho điều này khá rõ ràng:việc che giấu việc tạo doanh thu từ cơ quan thuế trở nên khó khăn hơn. Tôi đã thấy các nhận xét rằng đó là một yêu cầu ở Tây Ban Nha và Bồ Đào Nha và tôi sẽ không ngạc nhiên nếu nó không phải là một yêu cầu ở nhiều quốc gia khác.

Vì vậy, nếu chúng ta chấp nhận rằng đó là một yêu cầu hợp lệ, trong những trường hợp nào thì các chuỗi số không có khoảng cách * là một vấn đề? Tư duy nhóm thường khiến bạn tin rằng điều đó luôn là như vậy, nhưng trên thực tế, đó chỉ là một vấn đề tiềm ẩn trong những trường hợp rất cụ thể.

  1. Dãy số không được có khoảng trống.
  2. Nhiều quy trình tạo ra các thực thể mà số đó được liên kết với nhau (ví dụ:hóa đơn).
  3. Các số phải được tạo tại thời điểm thực thể được tạo.

Nếu tất cả các yêu cầu này phải được đáp ứng thì bạn có một điểm cần tuần tự hóa trong ứng dụng của mình và chúng ta sẽ thảo luận về điều đó trong giây lát.

Trước tiên, hãy nói về các phương pháp triển khai yêu cầu về chuỗi số nếu bạn có thể bỏ bất kỳ yêu cầu nào trong số đó.

Nếu chuỗi số của bạn có thể có khoảng trống (và bạn có nhiều quy trình yêu cầu tạo số ngay lập tức) thì hãy sử dụng đối tượng Oracle Sequence. Họ đang có hiệu suất rất cao và những tình huống có thể có khoảng trống đã được thảo luận rất kỹ. Không quá khó để giảm thiểu lượng số bị bỏ qua bằng cách nỗ lực thiết kế để giảm thiểu khả năng xảy ra lỗi quy trình giữa việc tạo số và thực hiện giao dịch, nếu điều đó là quan trọng.

Nếu bạn không có nhiều quy trình tạo các thực thể (và bạn cần một chuỗi số không có khoảng trống phải được tạo ngay lập tức), như trường hợp tạo hàng loạt hóa đơn, thì bạn đã có một điểm tuần tự. Bản thân điều đó có thể không phải là vấn đề và có thể là một cách hiệu quả để thực hiện hoạt động cần thiết. Trong trường hợp này, việc tạo ra các số không có khoảng cách là khá đơn giản. Bạn có thể đọc giá trị lớn nhất hiện tại và áp dụng giá trị tăng dần cho mọi thực thể bằng một số kỹ thuật. Ví dụ:nếu bạn đang chèn một lô hóa đơn mới vào bảng hóa đơn của mình từ một bàn làm việc tạm thời, bạn có thể:

insert into
  invoices
    (
    invoice#,
    ...)
with curr as (
  select Coalesce(Max(invoice#)) max_invoice#
  from   invoices)
select
  curr.max_invoice#+rownum,
  ...
from
  tmp_invoice
  ...

Tất nhiên, bạn sẽ bảo vệ quy trình của mình để chỉ một phiên bản có thể chạy tại một thời điểm (có thể là với DBMS_Lock nếu bạn đang sử dụng Oracle) và bảo vệ số hóa đơn bằng một khóa duy nhất đối chiếu và có thể kiểm tra các giá trị bị thiếu bằng mã riêng biệt nếu bạn thực sự, thực sự quan tâm.

Nếu bạn không cần tạo các số ngay lập tức (nhưng bạn cần chúng không có khoảng trống và nhiều quy trình tạo ra các thực thể) thì bạn có thể cho phép các thực thể được tạo và giao dịch được cam kết, sau đó để tạo số thành một lô duy nhất Công việc. Cập nhật trên bảng thực thể hoặc chèn vào một bảng riêng biệt.

Vì vậy, nếu chúng ta cần bộ ba của việc tạo tức thì một chuỗi số không có khoảng cách bằng nhiều quá trình? Tất cả những gì chúng tôi có thể làm là cố gắng giảm thiểu khoảng thời gian lặp lại trong quá trình này và tôi đưa ra lời khuyên sau đây và hoan nghênh mọi lời khuyên bổ sung (tất nhiên là lời khuyên phản bác).

  1. Lưu trữ các giá trị hiện tại của bạn trong một bảng chuyên dụng. KHÔNG sử dụng một chuỗi.
  2. Đảm bảo rằng tất cả các quy trình sử dụng cùng một mã để tạo các số mới bằng cách gói nó trong một hàm hoặc thủ tục.
  3. Truy cập nối tiếp vào trình tạo số bằng DBMS_Lock, đảm bảo rằng mỗi chuỗi đều có khóa chuyên dụng riêng.
  4. Giữ khóa trong trình tạo chuỗi cho đến khi giao dịch tạo thực thể của bạn hoàn tất bằng cách mở khóa khi cam kết
  5. Trì hoãn việc tạo số cho đến thời điểm cuối cùng có thể.
  6. Xem xét tác động của lỗi không mong muốn sau khi tạo số và trước khi hoàn tất cam kết - ứng dụng sẽ khôi phục một cách duyên dáng và giải phóng khóa hay nó sẽ giữ khóa trên trình tạo chuỗi cho đến khi phiên ngắt kết nối sau đó? Dù sử dụng phương pháp nào, nếu giao dịch không thành công thì (các) số chuỗi phải được “trả lại cho nhóm”.
  7. Bạn có thể gói gọn toàn bộ trong một trình kích hoạt trên bảng của thực thể không? Bạn có thể đóng gói nó trong một bảng hoặc lệnh gọi API khác để chèn hàng và tự động thực hiện việc chèn không?

Bài báo gốc



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Có thể thay đổi thứ tự tự nhiên của các cột trong Postgres không?

  2. Tìm các hàng có nhiều trường trùng lặp với Active Record, Rails &Postgres

  3. GroupingError:ERROR:cột phải xuất hiện trong mệnh đề GROUP BY hoặc được sử dụng trong một hàm tổng hợp

  4. psycopg2:chèn nhiều hàng với một truy vấn

  5. connect.select_value chỉ trả về các chuỗi trong postgres với pg gem