+1

ID

ID đã quen thuộc với chúng ta. Những gì chúng ta khai báo ra thì đều có ID. ID đôi khi không chỉ là dữ liệu chứng minh một thực thể là duy nhất mà còn có thể mang nhiều ý nghĩa hơn thế. Hãy cùng xem xét một số dạng ID thường thấy.

ID là số nguyên tăng dần

Đây là cách phổ biến, đơn giản để đặt ID cho một họ thực thể. Ưu điểm là nhanh, gọn, dễ cài đặt và an toàn. Các hệ thống thường tạo một bộ sinh chuỗi duy nhất cho một khai báo ID. Bộ sinh chuỗi này không thể truy cập cùng lúc và chỉ sinh số mới lớn hơn số cũ, không thể rollback (Việc sinh ID này không phải là MAX(ID) + 1). Đơn giản là thế như ID này cũng có thể đem lại một số ý nghĩa trực quan vì nó liên quan đến thời gian khởi tạo của thực thể. Việc sắp xếp theo trình tự thời gian hay tìm kiếm thực thể mới nhất có thể sử dụng ID thay cho Created DateTime.

Thông thường, các ID này chỉ là duy nhất trong họ của nó. Hoặc bạn có thể cài đặt để nó là duy nhất trong hệ thống của bạn, tức cả hệ thống chỉ sử dụng một bộ sinh chuỗi duy nhất. Điều này ảnh hưởng đến việc import/export dữ liệu giữa các hệ thống. Ngoài ra, loại ID này thương bị giới hạn cận trên vì nó thường là số nguyên 32 bit hoặc 64 bit. Một điểm yếu nữa là các hệ thống phân tán. Để dùng ID này, chúng ta cần có một service sinh chuỗi để chia sẻ giữa các điểm.

ID là số ngẫu nhiên duy nhất

Tức là UUID hay GUID. Một thuật toán ngẫu nhiên sẽ sinh ra một số nguyên có tỉ lệ rất thấp bị trùng trong phạm vi "Universal" hoặc "Global". Loại ID này dễ sử dụng. Nó khắc phục một số nhược điểm của loại ID chuỗi số như là import/export thuận tiện, hoạt động tốt trong các hệ thống phân tán, coi như không có giới hạn cận trên. Bù lại ưu điểm đó thì ID này cồng kềnh (như GUID có kích thước 16 byte, so với 8 byte của int64), khó đọc, không có ý nghĩa về thời gian nên ảnh hưởng tới sắp xếp (mặc dù datetime cũng là một số nguyên và sắp xếp theo datetime cũng nhanh như ID, nhưng datetime không được đặt là clustered index như ID (primary key), do đó truy xuất bản ghi chậm hơn dùng ID).

ID có định dạng riêng

Đôi khi lập trình viên muốn ID có nhiều ý nghĩa hơn và cũng muốn lấy ưu điểm của cả hai kiểu ID trên, họ tự định nghĩa ra loại ID của riêng mình. Loại này cũng phổ biến trong cuộc sống.

Ví dụ đơn giản nhất là số CCCD của chúng ta. Số CCCD gồm 12 chữ số, 3 chữ số đầu là tỉnh thành nơi đăng ký khai sinh, 3 chữ số sau là giới tính và năm sinh, 6 chữ số còn lại là ngẫu nhiên. Định dạng này giúp phân loại thông tin nhanh hơn, gọn hơn GUID nhưng lớn hơn int64, cũng dễ thuộc hơn một số nguyên bất kì. Hãy chú ý rằng CCCD khẳng định: Một tỉnh thành trong một năm sẽ không sinh ra tới 1 triệu bé trai hoặc bé gái. Với thực tế rằng cả nước hiện tại chỉ có hơn 1 triệu em bé sinh ra mỗi năm thì phát biểu trên hoàn toàn hợp lý. Việc dùng tới 6 chữ số thực chất là để số dễ đọc dễ nhớ hơn (chúng ta đọc mỗi 3 chữ số một lượt).

Việc xây dựng loại ID giúp chúng ta tối ưu theo mục đích của hệ thống, và nó cũng là một thách thức trong các hệ thống phân tán lớn và hiệu năng cao. Điều này là một điểm thú vị của việc xây dựng định dạng ID riêng và có đặc tính kĩ nghệ - engineering. Cùng xem xét facebook, chúng ta nên xây dựng ID cho user và post thế nào?

  • User không phải loại dữ liệu tăng chóng mặt theo thời gian, cũng không quan trọng user mới hay cũ, chúng ta dùng UUID là đủ (không phát sinh thêm chi phí nào, như là tạo một dịch vụ tạo ID chung).
  • Post được sinh ra số lượng lớn từng ngày, các post mới được truy vấn liên tục. Sẽ tốt hơn nhiều nếu ID của post tuyến tính với thời gian và một dịch vụ sinh hàng triệu ID mỗi giây cũng là một thách thức không nhỏ.

Một trường hợp khác như là ID của một bức ảnh. Instagram có hàng ngàn bức ảnh đưa lên mỗi giây, kho chứa hàng tỉ bức ảnh. Khi truy vấn 1 bức ảnh, ID được gửi lên và bạn truy vấn trong DB hoặc từ dịch vụ cache nào đấy để tìm cho được thông tin địa chỉ vật lý của bức ảnh, hàng tỉ bản ghi như thế. Nếu chúng ta có thể đưa tất cả các thông tin đó vào ID của bức ảnh thì việc tìm địa chỉ vật lý của bức ảnh sẽ bớt đi 1 dịch vụ truy vấn cũng như 1 dịch vụ lưu trữ thông tin cần truy vấn. Hãy để ý google drive: tất cả thông tin trên preview URL cũng như tên file tải về đều là UUID, chỉ có tên file hiển thị trên giao diện mà thôi, và preview URL cũng đã chứa các thông tin địa chỉ vật lý của file. Tất nhiên google drive khác instagram vì nội dung của instagram là ảnh và người dùng chia sẻ ảnh với nhau, việc có một URL đẹp là cần thiết so với URL đậm tính kĩ thuật của google drive. Việc tối ưu trong các hệ thống thường là tổng hợp từ việc tối ưu mỗi nơi một chút. Trong một số trường hợp, ID có thể là một vũ khí mạnh trong bài toán tối ưu: giảm thiểu chi phí xử lý mà URL vấn thống nhất, gọn gàng. Một câu hỏi đặt ngược lại là nếu dùng ID như một cách xác định địa chỉ file vật lý, điều gì xảy ra nếu phát sinh nhu cầu di chuyển file?

Thách thức về ID trong hệ thống phân tán lớn

Cơ bản thì chúng ta dùng UUID là cũng đủ. Trong một số trường hợp cần dạng ID tùy chỉnh, câu thần chú là: Chia để trị. Giống như cách chúng ta làm với CCCD. Thách thức ở đây có lẽ là việc chúng ta lựa chọn những tham số nào để chia ra. Đôi khi các yếu tố kĩ thuật cũng có thể cấu thành ID, ví dụ như số của datacenter, nhưng tốt nhất ID chỉ nên mang các tham số mang tính nghiệp vụ. Việc đánh giá cận trên của các tham số cũng rất quan trọng. Ví dụ với CCCD có thể lỗi trên lý thuyết. Chữ số thứ 4 chỉ giới tính. Thế kỉ 20 thì là 0 cho nam, 1 cho nữ. Thế kỉ 21 thì 2 cho nam, 3 cho nữ. Cứ thế tiếp tục. Nếu một ngày Les, Gay, Trans, Bi cũng được tính thì 1 chữ số sẽ không đủ nữa, hệ thống sẽ sai hết.

Kết bài

Trong thực tế công việc, chúng ta quan tâm chủ yếu đến ID là số tự tăng hoặc UUID. Tất nhiên nếu có cơ hội để tạo một định dạng ID cho riêng sản phẩm của mình thì cũng vui.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí