2009-07-09 22 views
9

Làm cách nào để mọi người tạo các số nguyên auto_incrementing cho một người dùng cụ thể trong một ứng dụng saas điển hình? Ví dụ: số hóa đơn cho tất cả hóa đơn cho một người dùng cụ thể sẽ được tự động tạo và bắt đầu từ 1. Trường id đường ray không thể được sử dụng trong trường hợp này, vì nó được chia sẻ giữa tất cả người dùng.Tạo các số liên tiếp trong ứng dụng saas đa người dùng

Tắt đầu của tôi, tôi có thể đếm tất cả các hóa đơn mà người dùng có và sau đó thêm 1, nhưng có ai biết giải pháp nào tốt hơn không?

Trả lời

4

giải pháp điển hình cho bất kỳ cơ sở dữ liệu quan hệ có thể là một bảng như

user_invoice_numbers (user_id int primary key clustered, last_id int) 

và một thủ tục lưu trữ hoặc một truy vấn SQL như

update user_invoice_numbers set last_id = last_id + 1 where user_id = @user_id 
select last_id from user_invoice_numbers where user_id = @user_id 

Nó sẽ làm việc cho người sử dụng (nếu mỗi người dùng có một vài đồng thời chạy các giao dịch) nhưng sẽ không hoạt động cho các công ty (ví dụ khi bạn cần các công ty_invoice_numbers) vì các giao dịch từ những người dùng khác nhau trong cùng một công ty có thể chặn lẫn nhau và sẽ có một nút cổ chai hiệu suất trong bảng này.

Yêu cầu chức năng quan trọng nhất bạn nên kiểm tra là liệu hệ thống của bạn có được phép có khoảng trống trong đánh số hóa đơn hay không. Khi bạn sử dụng auto_increment tiêu chuẩn, bạn cho phép khoảng trống, bởi vì trong hầu hết cơ sở dữ liệu tôi biết, khi bạn quay lại giao dịch, số tăng lên sẽ không được cuộn lại. Lưu ý điều này, bạn có thể cải thiện hiệu suất bằng cách sử dụng một trong các nguyên tắc sau đây

1) Loại trừ quy trình bạn sử dụng để nhận số mới từ các giao dịch đang chạy dài. Giả sử rằng chèn vào hóa đơn thủ tục là một giao dịch dài chạy với logic phía máy chủ phức tạp. Trong trường hợp này, trước tiên bạn có được một id mới, và sau đó, trong giao dịch riêng biệt, hãy chèn hóa đơn mới. Nếu giao dịch cuối cùng sẽ được khôi phục, số tự động sẽ không giảm.Nhưng user_invoice_numbers sẽ không bị khóa trong thời gian dài, vì vậy nhiều người dùng đồng thời có thể chèn hóa đơn cùng lúc

2) Không sử dụng cơ sở dữ liệu giao dịch truyền thống để lưu trữ dữ liệu với id cuối cùng cho mỗi người dùng. Khi bạn cần duy trì danh sách các khóa và giá trị đơn giản, có rất nhiều công cụ cơ sở dữ liệu nhỏ nhưng nhanh có thể làm việc đó cho bạn. List of Key/Value databases. Có lẽ memcached là phổ biến nhất. Trong quá khứ, tôi đã thấy các dự án có kho khóa/giá trị đơn giản được triển khai bằng Windows Registry hoặc thậm chí là một hệ thống tệp. Có một thư mục trong đó mỗi tên tệp là khóa và bên trong mỗi tệp là id cuối cùng. Và giải pháp thô này vẫn tốt hơn sau đó sử dụng bảng SQL, bởi vì ổ khóa đã được ban hành và phát hành rất nhanh chóng và không tham gia vào phạm vi giao dịch.

Vâng, nếu đề xuất tối ưu hóa của tôi có vẻ là quá phức tạp cho dự án của bạn, hãy quên điều này ngay bây giờ, cho đến khi bạn thực sự sẽ gặp sự cố về hiệu suất. Trong hầu hết các dự án, phương pháp đơn giản với một bảng bổ sung sẽ hoạt động khá nhanh.

+0

Tôi không cho phép chỉnh sửa/xóa hóa đơn, để đơn giản hóa toàn bộ điều một chút (không có khoảng trống). Nhưng tôi không lo lắng về hiệu suất ngay bây giờ. Cảm ơn –

+0

memcached không phải là công cụ cơ sở dữ liệu: http://code.google.com/p/memcached/wiki/FAQ#How_can_I_use_memcached_as_a_database? –

+0

Nếu bạn sử dụng bất kỳ công nghệ nào có thể dẫn đến khoảng trống (khi nó xuất hiện từ câu trả lời tự động trả lời này) thì bạn có thể giảm ganh đua bằng cách cho phép nhận trước các đoạn từ chuỗi. Trường hợp xấu nhất bạn mất đoạn không sử dụng. – djna

0

Không chắc đây có phải là giải pháp tốt nhất hay không, nhưng bạn có thể lưu ID hóa đơn cuối cùng trên Người dùng và sau đó sử dụng ID đó để xác định ID tiếp theo khi tạo Hoá đơn mới cho Người dùng đó. Nhưng giải pháp đơn giản này có thể có vấn đề với tính toàn vẹn, sẽ cần phải cẩn thận.

+0

Có một ID Invoice thuộc tính thực sự thuộc về một đối tượng người dùng? Đó là một giải pháp thực dụng nhưng không phải là một cho những người theo chủ nghĩa thuần túy! –

+0

Nếu có yêu cầu số hóa đơn là sequeential cho mỗi người dùng, thì "latestInvoiceNumberForThisUser" dường như được liên kết chặt chẽ với người dùng. – djna

+0

Có, cũng được lập luận. –

2

Bạn có thể giới thiệu một bảng khác được liên kết với bảng "người dùng" của bạn theo dõi số hóa đơn gần đây nhất cho người dùng. Tuy nhiên, việc đọc giá trị này sẽ dẫn đến truy vấn cơ sở dữ liệu, vì vậy bạn cũng có thể nhận được một số hoá đơn của người dùng và thêm một số, như bạn đã đề xuất. Dù bằng cách nào, đó là một cơ sở dữ liệu hit.

2

Nếu số hóa đơn độc lập cho từng người dùng/khách hàng thì có vẻ như trường "lastInvoice" trong một số lưu trữ liên tục (ví dụ: bản ghi DB) được liên kết với người dùng là khá khó tránh khỏi. Tuy nhiên điều này có thể dẫn đến một số tranh cãi cho số "mới nhất".

Có thực sự quan trọng nếu chúng tôi gửi hóa đơn người dùng 1, 2, 3 và 5 và không bao giờ gửi hóa đơn cho họ 4? Nếu bạn có thể thư giãn yêu cầu một chút.

Nếu yêu cầu thực sự là "mọi số hóa đơn phải là duy nhất" thì chúng ta có thể xem tất cả các thủ thuật tạo id bình thường và các thủ thuật này có thể khá hiệu quả.

Đảm bảo rằng các số được thêm vào tính phức tạp, nó có mang lại lợi ích kinh doanh không?

+0

có, bởi vì nó là một ứng dụng kế toán, con số cần phải tự động tăng số nguyên. Vì vậy, nó cần phải được khá vững chắc quá. –

0

Bạn có thực sự muốn tạo ID hóa đơn theo định dạng gia tăng không? Điều này sẽ không mở lỗ hổng bảo mật (trong đó, nếu người dùng có thể đoán được việc tạo số hóa đơn, họ có thể thay đổi nó trong yêu cầu và có thể dẫn đến việc tiết lộ thông tin). Tôi lý tưởng sẽ tạo các số ngẫu nhiên (và theo dõi các số đã sử dụng). Điều này ngăn ngừa va chạm là tốt (Cơ hội va chạm được giảm khi các con số được phân bổ ngẫu nhiên trên một phạm vi).

+1

Ở một số quốc gia, số ngẫu nhiên không hợp pháp của nó. Phải là các chuỗi tuần tự để kiểm tra của Chính phủ. – Juanin

Các vấn đề liên quan