Tôi có nên thêm giới hạn độ dài tùy ý cho các cột VARCHAR không?


35

Theo tài liệu của PostgreSQL , không có sự khác biệt về hiệu năng giữa VARCHAR, VARCHAR(n)TEXT.

Tôi có nên thêm giới hạn độ dài tùy ý vào cột tên hoặc địa chỉ không?

Chỉnh sửa: Không phải là bản sao của:

Tôi biết CHARloại này là một di tích của quá khứ và tôi không chỉ quan tâm đến hiệu suất mà còn những ưu và nhược điểm khác như Erwin đã nêu trong câu trả lời tuyệt vời của mình.

Câu trả lời:


45

Câu trả lời là không .
Đừng thêm một công cụ sửa đổi độ dài varcharnếu bạn có thể tránh nó. Hầu hết thời gian, bạn thực sự không cần hạn chế độ dài. Chỉ cần sử dụng textcho tất cả các dữ liệu nhân vật. Tạo điều đó varchar(không có công cụ sửa đổi độ dài) nếu bạn cần duy trì khả năng tương thích với RDBMS không có text.

Hiệu suất là gần như giống nhau - textmột chút nhanh hơn trong những tình huống hiếm hoi , và giúp bạn tiết kiệm các chu kỳ cho việc kiểm tra về độ dài.

Nếu bạn thực sự cần phải thực thi một độ dài tối đa, vẫn sử dụng textvà thêm một ràng buộc kiểm tra cho điều đó:

ALTER TABLE tbl ADD CONSTRAINT tbl_col_len CHECK (length(col) < 51);

Bạn có thể sửa đổi hoặc loại bỏ một ràng buộc như vậy bất cứ lúc nào mà không phải lộn xộn với định nghĩa bảng và tất cả các đối tượng tùy thuộc (chế độ xem, chức năng, khóa ngoại, ...)

Với chiều dài từ bổ nghĩa bạn chỉ cần chạy vào các vấn đề như thế này hay này hay này ...

PostgreQuery 9.1 đã giới thiệu một tính năng mới để giảm bớt phần nào nỗi đau. Tôi trích dẫn các ghi chú phát hành ở đây :

Cho phép ALTER TABLE ... SET DATA TYPEtránh viết lại bảng trong các trường hợp thích hợp (Noah Misch, Robert Haas)

Ví dụ, chuyển đổi một varcharcột thành văn bản không còn yêu cầu viết lại bảng. Tuy nhiên, việc tăng ràng buộc độ dài trên một varcharcột vẫn yêu cầu viết lại bảng.


Tôi nghĩ rằng câu trả lời này sẽ tốt hơn rất nhiều nếu chỉ đơn giản là "không thêm giới hạn tùy ý vào cơ sở dữ liệu thực sự." Tôi cảm thấy rất nhiều câu trả lời này cần sửa chữa và thêm thông tin, nhưng nó hoàn toàn lạc đề và sẽ làm sao lãng kết luận của bạn mà tôi hoàn toàn đồng ý.
Evan Carroll

Có, tất cả dựa trên các phiên bản Postgres trước 9,1 - 6 năm trước. Một chút bụi bây giờ, nhưng lời khuyên cơ bản vẫn còn tốt.
Erwin Brandstetter

Việc thêm một ràng buộc kiểm tra cho mỗi cột văn bản cho mục đích kiểm tra độ tỉnh táo và đảm bảo lỗi trong máy khách không sử dụng hết dung lượng đĩa của cơ sở dữ liệu bằng cách chèn một văn bản rất lớn?

@ Mã: Đó là một lựa chọn khả thi. Nếu bạn có nhiều cột có cùng ràng buộc, hãy xem xét các tên miền . Hoặc xét varchar(n)cho cùng, vì đơn giản - nếu nhược điểm thường không ảnh hưởng đến bạn. (Giới hạn không phải là tùy ý trong trường hợp của bạn nếu bạn muốn thực thi một độ dài tối đa thực tế.)
Erwin Brandstetter

12

Nếu bạn thấy giới hạn độ dài là một loại ràng buộc kiểm tra để đảm bảo bạn xác thực dữ liệu, thì có thêm một giới hạn. Trên thực tế bạn có thể muốn không sử dụng một định nghĩa chiều dài nhưng một hạn chế kiểm tra thực thay vào đó, để làm thay đổi giới hạn nhanh hơn.

Để thay đổi (tăng) giới hạn độ dài, bạn cần chạy ALTER TABLEmột khoảng thời gian có thể mất nhiều thời gian để hoàn thành (do có thể viết lại bảng) trong thời gian khóa bảng độc quyền là cần thiết.

Thay đổi (nghĩa là bỏ và tạo lại) một ràng buộc kiểm tra là một thao tác rất ngắn gọn và chỉ yêu cầu đọc dữ liệu của bảng, nó sẽ không thay đổi bất kỳ hàng nào. Vì vậy, điều đó sẽ nhanh hơn rất nhiều (điều này có nghĩa là khóa bàn độc quyền sẽ được giữ trong một khoảng thời gian ngắn hơn nhiều).

Trong quá trình vận hành, không có sự khác biệt nào giữa a text, a varcharhoặc varchar(5000)cột.


Vì tò mò, tại sao bạn nghĩ rằng kiểm tra độ dài này không thể được thực hiện trên ứng dụng khách trong khi thu thập dữ liệu?
PirateApp

4
@PirateApp: bởi vì rất thường xuyên sẽ có nhiều hơn một ứng dụng hoặc một số nguồn dữ liệu bên ngoài (nghĩ rằng nhập hàng loạt hàng đêm). Và hầu như luôn luôn cơ sở dữ liệu (và dữ liệu) sống lâu hơn một ứng dụng.
a_horse_with_no_name

2

Câu hỏi cụ thể là liệu có thêm giới hạn độ dài tùy ý vào các cột VARCHAR không?

Do đó, câu trả lời chỉ đơn giản là "không". Không có gì có thể biện minh cho việc thêm một giới hạn tùy ý như bạn sẽ làm trong các cơ sở dữ liệu kém hơn hỗ trợ varchar(max)hoặc sử dụng các quy ước như thế nào varchar(255). Tuy nhiên, nếu thông số kỹ thuật giải quyết một giới hạn, tôi nghĩ rằng câu trả lời trở nên phức tạp hơn nhiều, đặc biệt là trên các phiên bản hiện đại của PostgreQuery. Và, vì điều đó, tôi sẽ nghiêng về .

Theo tôi, giới hạn là một lựa chọn sáng suốt nếu thông số kỹ thuật yêu cầu. Đặc biệt là cho khối lượng công việc hợp lý hơn. Nếu không có lý do nào khác để bảo tồn dữ liệu meta.

Từ câu trả lời của tôi ở đây, hiệu suất chỉ mục cho CHAR vs VARCHAR (Postgres) , nơi tôi giải quyết giá trị của siêu dữ liệu.

Nếu tôi tìm thấy một thông số có các khóa văn bản có độ dài thay đổi có ý nghĩa và tôi tin rằng nó có độ dài tối đa không đổi, tôi cũng sẽ sử dụng varchar. Tuy nhiên, tôi không thể nghĩ ra bất cứ điều gì phù hợp với tiêu chí đó.


1

Có vẻ như có thể có một số khác biệt về hiệu suất nếu VARCHARthường xuyên được sử dụng để lưu trữ các chuỗi rất lớn, vì "các chuỗi dài được hệ thống nén tự động" và "các giá trị rất dài cũng được lưu trữ trong các bảng nền." Về mặt lý thuyết, điều này có nghĩa là một khối lượng lớn yêu cầu cho trường chuỗi rất dài sẽ chậm hơn so với trường chuỗi ngắn. Có lẽ bạn sẽ không bao giờ gặp phải vấn đề này, vì tên và địa chỉ sẽ không quá dài.

Tuy nhiên, tùy thuộc vào cách bạn sử dụng các chuỗi này bên ngoài cơ sở dữ liệu của mình, bạn có thể muốn thêm một giới hạn thực tế để tránh lạm dụng hệ thống. Ví dụ: nếu bạn đang hiển thị tên và địa chỉ trên một biểu mẫu ở đâu đó, bạn có thể không hiển thị toàn bộ đoạn văn bản trong trường "tên", do đó, sẽ giới hạn cột tên ở mức 500 nhân vật.


1
AFAIK không có sự khác biệt trong các trường văn bản và văn bản TOASTing.
dezso

VARCHARlà đường cú pháp hoàn toàn cho TEXTPostgres, không có sự khác biệt trong xử lý lưu trữ; lưu trữ nén so với bảng nền mà bạn đề cập được thực hiện dựa trên chiều dài thực tế của dữ liệu trong cột chứ không phải trên siêu dữ liệu cột. Các cột văn bản được lưu trữ bên trong dưới dạng varlenacấu trúc C (là mảng có độ dài thay đổi với 4 byte đầu tiên lưu trữ độ dài khi tạo / cập nhật) và chính cấu trúc này được tối ưu hóa dựa trên chiều dài của nó.
cowbert
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.