Phải làm gì khi một trường trong bảng tiếp cận với số nguyên 32 bit được ký hoặc không dấu tối đa?


14

Trong bất kỳ cơ sở dữ liệu cụ thể nào lưu giữ hồ sơ người dùng dưới dạng trường tăng tự động duy nhất (vì lợi ích của ví dụ, tin nhắn giữa người dùng) ... phải làm gì khi thời gian đến và nó tiếp cận số được ký tối đa hoặc không dấu của kiểu dữ liệu hiện tại? (Một INT 32 bit)? Tôi đoán rằng máy chủ cơ sở dữ liệu sẽ tràn khi cố gắng gán số (2∧32) -1 cho mục tiếp theo, vì vậy, làm thế nào để tránh điều đó xảy ra (mà không thay đổi kiểu dữ liệu, vì lợi ích của câu hỏi) và tiếp tục thêm hồ sơ? Bạn sẽ làm gì?

Tại sao tôi sử dụng INT và không, ví dụ, VARCHARS?

Đã vài ngày kể từ khi tôi tự hỏi mình câu hỏi giả định này và tôi muốn biết một chuyên gia sẽ làm gì.

Câu trả lời:


12

Nói chung, bạn sẽ sử dụng các số nguyên thay vì varchars vì chúng tiêu tốn ít dung lượng hơn, có kiểu sắp xếp được hiểu rõ là nhanh để lập chỉ mục, vv Các số nguyên là kiểu dữ liệu tự nhiên của CPU và do đó hiệu suất nói chung là tối ưu. Thông thường một số nguyên là 4 byte, tương đương với chỉ 4 ký tự trong một varchar (không phải unicode).

Nếu bạn lo lắng về việc hết dung lượng với loại INT, hãy thử BIGINT, cung cấp cho bạn các số 8 byte. Giới hạn về điều này là khá lớn và có lẽ bạn sẽ hết dung lượng đĩa trước khi bạn đạt đến giới hạn hồ sơ đó :-) Hiệu suất của BIGINT cũng sẽ rất tốt, đặc biệt là nhiều máy chủ hiện nay cũng 64 bit .

Câu trả lời cho phần đầu tiên của câu hỏi của bạn về những gì xảy ra khi bạn hết INTs không đơn giản, đặc biệt như bạn đã nói mà không thay đổi kiểu dữ liệu thành BIGINT. Về cơ bản, bạn không thể làm được gì nhiều và những gì bạn có thể làm bị hạn chế rất nhiều bởi bản chất của dữ liệu trong cơ sở dữ liệu của bạn. Hồ sơ nào là khóa ngoại đối với dữ liệu này? Bạn vẫn cần tất cả dữ liệu trong bảng đó và các hồ sơ liên quan? Giả định rằng bạn có thể lưu trữ rất nhiều dữ liệu ban đầu (và dữ liệu liên quan của nó), thì điều duy nhất tôi có thể đề xuất là di chuyển dữ liệu ra khỏi bảng (giả sử là 1 đến X triệu bản ghi đầu tiên), sau đó Đặt lại hạt giống nhận dạng thành 1. Có tất cả các loại lý do mặc dù tôi không đề xuất nó - ví dụ: có nhiều đoạn mã tôi đã thấy làm những việc như kiểm tra giá trị tối đa của trường id, để xem những gì vừa được thêm vào, và điều đó sẽ không hoạt động (và không nên thực hiện). Ngoài ra, mọi người cho rằng bản ghi N đã được tạo trước N + 1. Không có câu trả lời dễ dàng tôi nghĩ.

Cuối cùng, tôi không biết về MySQL, nhưng SQL Server sẽ báo lỗi tràn nếu bạn đạt đến giới hạn.


1
Tôi hài lòng với một câu trả lời chi tiết như vậy. Cảm ơn lời giải thích của thỏa thuận VARCHAR, INT và BIGINT. Vì câu hỏi chỉ là giả thuyết, tôi tự hỏi điều gì sẽ xảy ra nếu cũng đạt đến giới hạn BIGINT. Câu hỏi được đưa ra bởi một bài đăng tôi thấy về facebook bằng cách sử dụng INT và đạt đến giới hạn, và tôi thấy nó hoàn toàn có thể. Lưu trữ sẽ hoạt động hoặc tạo một bảng thứ hai với một câu lệnh có điều kiện (như bạn đã nói, sẽ yêu cầu các tập lệnh cũng được cập nhật, và nó sẽ khá phức tạp). Nhìn chung, câu trả lời tuyệt vời. Tôi đánh giá cao thời gian thực hiện.
AeroCross

9

Một điểm bị bỏ qua là nhiều người dân bắt đầu số tự động hoặc danh tính ở mức 1 do đó mất một nửa phạm vi có thể ngay lập tức (đối với đã ký)

Bạn chỉ cần xác định lại số để bắt đầu ở -1, tăng -1 trong trường hợp này.

Có thể cho rằng, nếu bạn từng mong muốn điền vào cột nhận dạng của mình thì bạn nên thiết kế cái này và sử dụng kiểu dữ liệu rộng hơn khi bắt đầu.

Xem câu hỏi gần đây oon SO: SQL Server 2008: điều gì đã xảy ra nếu danh tính vượt qua giá trị tối đa của int?


Thật logic khi tôi sử dụng một kiểu dữ liệu rộng hơn (đối với một bảng có thể THAT lượng dữ liệu đó), nhưng vì đó là một câu hỏi giả định, tôi muốn có một cái nhìn sâu sắc. Nếu được ký, điều đó có thể hoạt động (nhưng tôi hơi lạ khi có khóa chính có số âm, IMHO) và tôi nghĩ nó khá thông minh. Nó sẽ dành thời gian cho DBA lưu trữ dữ liệu tích cực và bắt đầu lại. Nếu không dấu, cũng ... vấn đề.
AeroCross

Ngoài ra, để sử dụng mức tăng -1 từ -1, bắt đầu từ (-2147483648) và tăng thêm 1. Nhưng vâng, sau khi bạn vượt qua INT_MAX thì bạn đã khá ổn và cần xem lại thiết kế và xóa chỉ mục cũ thay thế nó với một cái mới lớn hơn. và nếu bạn vượt qua BIGINT không dấu thì tôi muốn đến làm việc với nhóm của bạn;)
jcolebrand

PostgreSQL sử dụng các chuỗi để tạo số id; câu lệnh CREATE SEQUENCE cho phép bạn chỉ định CYCLE, lệnh này sẽ chỉ bao quanh nếu bạn đạt được giá trị tối đa. (Hoặc giá trị tối thiểu, nếu bạn đang đi theo hướng khác.) Tùy chọn CYCLE hiện đang ở trong các tiêu chuẩn SQL. (Kể từ ít nhất 2003.)
Mike Sherrill 'Cat Recall'

4

LỚN LỚN? Haha. Đầu tiên tìm hiểu làm thế nào để đạt được sự bất tử. INT UNSIGNED (4 tỷ) là đủ khó để đạt được. 100 CHERTN mỗi giây sẽ tiến gần đến mức tràn INT trong một năm. BIGINT sẽ mất vài tỷ năm.

Để khắc phục: ALTER TABLE foo MODIFY COLUMN id BIGINT KHÔNG ĐƯỢC ĐĂNG KÝ KHÔNG NULL AUTO_INCREMENT; Nhưng điều đó sẽ mất nhiều giờ vì nó sẽ sao chép qua bảng (có gần 4 tỷ hàng, phải không?) Và xây dựng lại tất cả các chỉ mục phụ. Lên kế hoạch trước.

Nói chung, khi bạn cố lưu trữ một số quá lớn cho một trường (ví dụ: 999 trong TINYINT KHÔNG ĐƯỢC KÝ), nó sẽ âm thầm giới hạn nó ở mức tối đa cho trường (255 trong trường hợp này). Có thể có "Cảnh báo", nhưng hầu hết mọi người không bận tâm kiểm tra cảnh báo. Nếu đó là một trường ĐỘC ĐÁO hoặc có các phím NGOẠI TỆ, bạn có thể gặp một lỗi nghiêm trọng hơn.

CHAR hoặc VARCHAR đang âm thầm cắt ngắn vào không gian có sẵn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.