2010-02-15 33 views
8

Tôi đang tìm một cách tốt để tạo ID đơn đặt hàng duy nhất. Bạn có thấy bất kỳ vấn đề nào với mã bên dưới không?Cách tạo số đơn đặt hàng duy nhất?

int customerId = 10000000; 

long ticks = DateTime.UtcNow.Ticks; 

long orderId = customerId + ticks; 

int orderNumber = orderId.GetHashCode(); 

Tôi sẽ kiểm tra xem số đó có duy nhất trong cơ sở dữ liệu không trước khi tạo thứ tự.

+2

Về lý thuyết, băm có thể va chạm. –

+0

Chắc chắn nó không thực sự độc đáo bạn đang tìm kiếm, chỉ là số thứ tự tiếp theo ... Tôi đồng ý với những người dân dưới đây nói về việc sử dụng một cột nhận dạng. – Paddy

+3

@Developer Art: Không có lý thuyết gì về nó. Hashes va chạm * mọi lúc *. Chỉ có khoảng bốn tỷ người trong số họ có sẵn, do đó, tất nhiên họ sẽ va chạm. –

Trả lời

7

Điều gì về việc có trường IDENTITY trong cơ sở dữ liệu làm điều đó cho bạn?

Nó cũng sẽ có lợi thế là số đơn hàng đã xóa/hủy sẽ không được sử dụng lại (có thể tốt hoặc thậm chí có thể được yêu cầu để tính toán).

0

NẾU bạn đang sử dụng SQL Server, bạn thực sự nên tra cứu đặc tả IDENTITY. Nó cho phép bạn làm điều này một cách dễ dàng và tốc độ.

Giải pháp của bạn không phải là duy nhất bởi vì mọi thứ có thể xảy ra quá nhanh trong hệ thống hai quá trình, chạy theo trình tự hoặc đồng thời, có thể nhận được cùng một giá trị đánh dấu.

+0

Id khách hàng sẽ thay đổi theo từng đơn đặt hàng. Tôi nghĩ rằng việc kết hợp Id khách hàng với bọ ve sẽ tạo ra giá trị duy nhất mà tôi theo sau. –

24

Nếu bạn lưu trữ bản ghi trong cơ sở dữ liệu, bạn thực sự nên xem xét các khả năng có sẵn ở đó để tạo khóa thay thế duy nhất. Trong SQLServer, đây sẽ là trường IDENTITY và trong Oracle, nó sẽ là trường sử dụng SEQUENCE để tạo một giá trị mới.

Nếu có một lý do thuyết phục tại sao bạn không thể sử dụng cơ sở dữ liệu của bạn để tạo ra một chìa khóa duy nhất, bạn nên nhìn vào một cái gì đó giống như một Guid - trong đó có một xác suất cao hơn mucher hơn ngày thời gian thao tác để tạo ra một giá trị duy nhất . Các hướng dẫn có thể được chuyển đổi một cách trivially thành các chuỗi, vì vậy mã định danh của bạn sẽ là một chuỗi trong trường hợp này.

Những gì bạn đang làm với băm không phải là ý tưởng hay. - không có gì mà người bảo đảm băm sẽ là duy nhất - và trong nhiều trường hợp họ thực sự va chạm. Các hướng dẫn - không cung cấp sự bảo đảm 100% về tính độc đáo trên các máy nhưng trên một máy duy nhất, chúng phải luôn là duy nhất. Và ngay cả trên các máy móc, cơ hội va chạm của chúng cực kỳ xa. Ngoài ra, việc sử dụng thời gian của máy như một cách để xây dựng giá trị cơ bản là tùy thuộc vào các điều kiện chủng tộc (như những gì Eric mô tả).

Hướng dẫn là giá trị 128 bit, vì vậy bạn không thể đại diện cho chúng là đơn giản int hoặc long. Nó sẽ yêu cầu bạn sử dụng chuỗi như ID của bạn, có thể hoặc không thể xảy ra trong trường hợp của bạn, tùy thuộc vào các cân nhắc khác (như bạn có kiểm soát mô hình dữ liệu hay không). Nếu có thể sử dụng chúng, sử dụng một Guid là rất dễ dàng:

string customerId = Guid.NewGuid().ToString(); // fetch new guid and save as string 
string orderNumber = Guid.NewGuid().ToString(); // same story here... 

Nếu bạn thực sự phải sử dụng một định dạng số, và bạn sẵn sàng từ bỏ một cách dễ dàng nhân rộng ứng dụng của bạn trên nhiều máy chủ, bạn có thể sử dụng một auto-incrementing số toàn cầu để cung cấp khóa duy nhất. Bạn sẽ phải nhân giống số này với giá trị sẵn có tiếp theo (max + 1) từ cơ sở dữ liệu của bạn khi ứng dụng khởi động. Bạn cũng sẽ phải bảo vệ giá trị này khỏi việc sử dụng đồng thời từ nhiều luồng.Tôi sẽ quấn trách nhiệm này trong một lớp học:

class static UniqueIDGenerator 
{ 
    // reads Max+1 from DB on startup 
    private static long m_NextID = InitializeFromDatabase(); 

    public static long GetNextID() { return Interlocked.Increment(ref m_NextID); } 
} 


EDIT:Trong ngày và tuổi tác, lý do thuyết phục để tạo ID duy nhất trong lớp ứng dụng của bạn hơn là ở cơ sở dữ liệu rất phổ biến . Bạn thực sự nên sử dụng các khả năng mà cơ sở dữ liệu cung cấp.

+4

+1 - Câu trả lời rất hay. – JasCav

0

Tôi muốn sử dụng cột IDENTITY và nếu không, hãy sử dụng System.Guid.NewGuid() để tạo GUID cho bạn.

14

Giả sử bạn có hai id khách hàng khác nhau 100 và chúng xảy ra cho cả hai đơn đặt hàng cách nhau 100 đơn vị thời gian. Tính độc đáo của bạn vừa đi ra ngoài cửa sổ.

Bạn nói rằng bạn sẽ kiểm tra cơ sở dữ liệu để tìm kiếm tính duy nhất; bạn không nói những gì bạn sẽ làm gì nếu có va chạm. Bạn cũng không nói những gì bạn sẽ làm gì về điều kiện chủng tộc; giả sử hai id thứ tự va chạm được tạo cùng một lúc, không có trong cơ sở dữ liệu. Bạn yêu cầu cơ sở dữ liệu trên hai chủ đề khác nhau cho dù mục là duy nhất; nó là. Sau đó bạn nhập cả hai, và tính duy nhất đã bị vi phạm ngay cả khi kiểm tra đã được thực hiện.

Đây thực sự là một cách thực sự tồi tệ để có được sự độc đáo. Điều tốt hơn là di chuyển nó vào lớp cơ sở dữ liệu. Bạn có thể duy trì bộ đếm đơn đặt hàng toàn cầu, an toàn và chỉ định mỗi đơn hàng mới số thứ tự cao nhất tiếp theo.

Ngẫu nhiên, trong nhiều năm, tôi đã hỏi một biến thể về câu hỏi này là câu hỏi phỏng vấn kỹ thuật. Tôi đã nhận thấy một mối tương quan mạnh mẽ giữa tập hợp những người cố gắng sử dụng thời gian như một nguồn độc đáo và tập hợp những người không được thuê. Thời gian là khủng khiếp nguồn duy nhất; nhiều thứ khác nhau có thể xảy ra cùng một lúc.

Điều thậm chí còn tệ hơn là sử dụng các số ngẫu nhiên. Các số ngẫu nhiên là một nguồn độc đáo thậm chí còn tồi tệ hơn so với dấu thời gian. Giả sử bạn có một trình tạo số ngẫu nhiên thực sự tạo ra các số nguyên 32 bit ngẫu nhiên cho các ID đơn đặt hàng. Bạn cần bao nhiêu đơn đặt hàng trước khi tỷ lệ cược tốt hơn năm mươi lăm năm mà bạn đã tạo hai đơn đặt hàng có cùng ID? Câu trả lời gây ngạc nhiên cho rất nhiều người: chỉ khoảng 77 nghìn trước khi có 50% cơ hội mà bạn đã tạo ra hai đơn hàng với cùng một số (và chỉ 9300 cho đến khi có 1% cơ hội.)

Hãy nhớ rằng: bạn là sau khi bảo đảm tính độc đáo. Không phải là có thể xảy ra tính độc đáo, nhưng đảm bảo chắc chắn rằng một số đơn hàng đề cập đến chính xác một đơn đặt hàng. Nếu đó là những gì bạn cần, thì hãy đảm bảo bạn thực hiện điều đó.

0
+1

Nếu bạn cho rằng id đơn hàng được tạo ngẫu nhiên bằng cách sử dụng ngẫu nhiên thực sự, đây là một ý tưởng * nguy hiểm khủng khiếp.Tỷ lệ nhận được một vụ va chạm giữa hai con số 32 bit thực sự ngẫu nhiên tăng lên> 50% chỉ sau 77000 lần thử! –

+0

@Eric: Bạn đúng, tôi không đề xuất ID đơn hàng # được tạo ngẫu nhiên, chỉ việc tạo số cần được thông báo về những cạm bẫy của các hoạt động như vậy, như bạn đã chỉ ra. Lý thuyết số ngẫu nhiên là một nơi tốt để tìm những cạm bẫy như vậy để họ có thể tránh được. –

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