Các thực tiễn tốt nhất hiện tại liên quan đến kích thước varchar trong SQL Server là gì?


12

Tôi đang cố gắng hiểu cách tốt nhất để quyết định các cột varchar lớn như thế nào, cả từ quan điểm lưu trữ và hiệu suất.

Hiệu suất
Từ nghiên cứu của tôi, có vẻ nhưvarchar (max) chỉ nên được sử dụng nếu bạn thực sự cần nó; nghĩa là, nếu cột phải chứa hơn 8000 ký tự, một lý do là thiếu lập chỉ mục (mặc dù tôi hơi nghi ngờ về việc lập chỉ mục trên các trường varchar nói chung. Mặc dù vậy, tôi khá mới đối với các nguyên tắc DB, vì vậy có lẽ điều đó không có cơ sở ) và nén (thêm một mối quan tâm lưu trữ). Trong thực tế, nhìn chung mọi người dường như chỉ khuyên bạn nên sử dụng những gì bạn cần, khi thực hiện varchar (n) .... quá khổ là xấu, bởi vì các truy vấn phải chiếm kích thước tối đa có thể. Nhưng nó cũng được tuyên bố rằng động cơ sẽ sử dụng một nửa kích thước được chỉ định làm ước tính kích thước thực tế trung bình của dữ liệu. Điều này có nghĩa là người ta sẽ xác định, từ dữ liệu, kích thước trung bình là bao nhiêu, nhân đôi nó và sử dụng như n. Đối với dữ liệu có độ biến thiên rất thấp nhưng khác không điều này có nghĩa là quá khổ gấp đôi so với kích thước tối đa, có vẻ như rất nhiều, nhưng có lẽ không phải vậy? Thông tin chi tiết sẽ được đánh giá cao.

Lưu trữ
Sau khi đọc về cách hoạt động của lưu trữ liên tiếp so với lưu trữ ngoài hàng và lưu ý rằng lưu trữ thực tế bị giới hạn đối với dữ liệu thực tế, đối với tôi, sự lựa chọn của n có rất ít hoặc không có liên quan đến lưu trữ (bên cạnh đó đảm bảo nó đủ lớn để chứa mọi thứ). Ngay cả khi sử dụng varchar (max) cũng không có bất kỳ tác động nào đến việc lưu trữ. Thay vào đó, mục tiêu có thể là giới hạn kích thước thực tế của mỗi hàng dữ liệu ở mức ~ 8000 byte nếu có thể. Đó có phải là một đọc chính xác về mọi thứ?

Bối cảnh
Một số dữ liệu khách hàng của chúng tôi dao động một chút, vì vậy chúng tôi thường làm cho các cột chỉ rộng hơn một chút so với mức cần thiết, lớn hơn 15-20% cho các cột đó. Tôi đã tự hỏi nếu có bất kỳ cân nhắc đặc biệt khác; ví dụ: một người mà tôi làm việc cùng đã bảo tôi sử dụng 2 ^ n - 1 kích thước (tôi không tìm thấy bằng chứng nào cho thấy điều đó ....)

Tôi đang nói về việc tạo bảng ban đầu. Một khách hàng sẽ cho chúng tôi biết rằng họ sẽ bắt đầu gửi cho chúng tôi một bảng mới và gửi dữ liệu mẫu (hoặc chỉ bộ dữ liệu sản xuất đầu tiên) mà chúng tôi xem xét và tạo một bảng ở cuối để giữ dữ liệu. Chúng tôi muốn làm cho bảng cuối cùng của chúng tôi để xử lý nhập khẩu trong tương lai cũng như những gì trong mẫu. Nhưng, một số hàng nhất định bị ràng buộc để có được lâu hơn, vì vậy chúng tôi đệm chúng.

Câu hỏi là bao nhiêu, và có hướng dẫn kỹ thuật không?


MongoDB sử dụng phân bổ đĩa 2 ^ n cho một tài liệu. SQL Server không sử dụng chiến lược này.
Michael Green

Câu trả lời:


18

Bất kể kiểu dữ liệu cụ thể, bạn cần có khả năng lưu trữ bất cứ thứ gì ứng dụng yêu cầu được lưu trữ. Bạn không thể chỉ định một cái gì đó nhỏ hơn kích thước tối đa của những gì thực sự sẽ được lưu.

Bạn cũng không cần, cũng không muốn chỉ định chiều dài cột lớn hơn kích thước thực tế tối đa sẽ được lưu trữ vì nhiều lý do: phân bổ bộ nhớ truy vấn, có khả năng lấp đầy kích thước hàng tối đa và không chừa bất kỳ chỗ nào để thêm cột vào tương lai, v.v.

Các cột nhị phân và chuỗi có độ dài thay đổi không có hàm ý lưu trữ mà các kiểu dữ liệu có độ dài cố định (chuỗi / nhị phân / số / ngày / vv) làm (mặc dù, một số hàm ý đó có thể bị vô hiệu hóa thông qua nén dữ liệu hoặc sử dụng SPARSEđịnh nghĩa cột Lựa chọn). Tuy nhiên, như bạn đã chỉ ra, ngay cả khi không có hàm ý lưu trữ trực tiếp, vẫn có hàm ý hiệu năng của việc đánh giá quá cao bộ nhớ cần thiết cho các truy vấn.

Hãy nhạy cảm. Chỉ sử dụng những gì bạn cần. Cân nhắc có thể được thực hiện nếu có xác suất cao rằng chiều dài cột sẽ cần tăng trong tương lai gần, nhưng hãy nhớ rằng việc mở rộng kích thước của cột dễ dàng hơn là giảm kích thước. Vâng, một số công việc sẽ được tham gia, nhưng vì công việc đó chỉ là "tiềm năng", trong khi ý nghĩa hiệu suất của việc định cỡ quá mức là "thực tế", nên tốt nhất là xác định các cột dựa trên những gì bạn thực sự cần, chứ không phải những gì bạn có thể - loại -sorta nghĩ rằng bạn có thể cần trong tương lai. Nhiều thay đổi được nói đến không bao giờ xảy ra, và thường những thay đổi được yêu cầu không thể lường trước được. Đi với những gì bạn biết.

Thay vào đó, mục tiêu có thể là giới hạn kích thước thực tế của mỗi hàng dữ liệu ở mức ~ 8000 byte nếu có thể.

Tôi không chắc chắn chính xác những gì bạn đang nhận được ở đây. SQL Server sẽ giới hạn vật lý của bạn chỉ hơn 8000 byte. Sử dụng các loại LOB - VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX), XML, và bị phản đối TEXT, NTEXTIMAGEcác loại - cho phép đi xa hơn giới hạn kích thước trang đầu tiên, nhưng đó chỉ là do cách đặt một con trỏ (16 hoặc nhiều byte, tùy thuộc vào loại, và tùy thuộc vào kích thước của giá trị được lưu ngoài hàng khi sử dụng các MAXloại). Giới hạn vật lý thực tế của trang dữ liệu không thay đổi.

Mục tiêu của bạn là sử dụng ít không gian vật lý nhất để lưu trữ những gì ứng dụng / doanh nghiệp cần lưu trữ mà không phá vỡ hoặc cắt bớt sao cho giá trị không đầy đủ làm mất ý nghĩa hoặc gây ra sự cố. Nếu bạn cần lưu trữ 12.000 ký tự, sau đó sử dụng VARCHAR(MAX)vì đó là những gì cần thiết. Nếu bạn đang lưu trữ một số điện thoại hoặc mã bưu chính / mã zip, thì việc sử dụng nó sẽ không khôn ngoan VARCHAR(100)và vô trách nhiệm khi sử dụng VARCHAR(MAX).

một số dữ liệu khách hàng của chúng tôi dao động một chút, vì vậy chúng tôi thường làm cho các cột chỉ rộng hơn một chút so với mức cần thiết, lớn hơn 15-20% cho các cột đó. Tôi đã tự hỏi nếu có bất kỳ cân nhắc đặc biệt khác;

Không phải tất cả các hệ thống đều có ít nhất một số dữ liệu dao động? Bất kỳ hệ thống lưu trữ tên của một người sẽ đủ điều kiện, phải không? Có một phương sai khá lớn về độ dài của tên. Và sau đó bạn có một người như Hoàng tử đi và đổi tên của họ thành một biểu tượng và bây giờ bạn có một vấn đề hoàn toàn khác không phải là chiều dài. Đây chỉ là cách mọi thứ.

Nhưng, để chơi người ủng hộ của quỷ trong giây lát: làm thế nào giá trị "lớn hơn 15-20% so với những gì cần thiết" không thể là giá trị thực sự cần thiết ? Hãy nói rằng có một cuộc thảo luận về việc thêm một cột mới và ai đó gợi ý 50 ký tự, sau đó một người khác nói, "tốt, 20% nữa là 60 vì vậy hãy làm 60 vì ai đó có thể có 60." Nếu đúng là một khách hàng có thể có 60, thì 60 là và luôn luôn là, giá trị thực sự cần thiết và 50 đã sai trong toàn bộ thời gian.

Tất nhiên, nó sẽ hữu ích nếu có một số dấu hiệu về nguồn dữ liệu vì:

  1. nếu bạn tạo "URL" 1024 và ai đó cần 1060, thì nó cần phải là 1060 (tương tự, nếu bạn tạo URL VARCHARvà nhận được khiếu nại rằng nó đang làm rối các ký tự Unicode hiện được phép trong tên miền, thì nó cần phải có NVARCHAR), nhưng
  2. nếu ai đó muốn thêm 1000 ký tự vào trường nhận xét giới hạn 500 ký tự, thì nó vẫn chỉ cần 500. Mọi người có thể bớt dài dòng trong các nhận xét (một thách thức lớn đối với tôi ;-), nhưng ProductSKUtốt hơn là đủ để phù hợp với tất cả của SKU của khách hàng.

Tôi đang nói về việc tạo bảng ban đầu. Một khách hàng sẽ cho chúng tôi biết rằng họ sẽ bắt đầu gửi cho chúng tôi một bảng mới và gửi dữ liệu mẫu (hoặc chỉ là tập dữ liệu sản xuất đầu tiên), chúng tôi xem xét và tạo một bảng ở cuối để giữ dữ liệu. Chúng tôi muốn làm cho bảng cuối cùng của chúng tôi để xử lý nhập khẩu trong tương lai cũng như những gì trong mẫu. Nhưng, một số hàng nhất định bị ràng buộc để có được lâu hơn, vì vậy chúng tôi đệm chúng. Câu hỏi là bao nhiêu, và có hướng dẫn kỹ thuật không?

Bạn đang thực hiện rất nhiều giả định ở đây. Chắc chắn một số lĩnh vực có thể trở nên lớn hơn. Nhưng sau đó một lần nữa, họ có thể không. Hoặc, một số có thể nhỏ hơn. Một số người có thể thay đổi từ không phải là Unicode sang Unicode (một khi họ nhận ra rằng thế giới đang ngày càng nhỏ hơn và người ta không thể cho rằng tên cuối cùng sẽ chỉ có các ký tự tiếng Anh ASCII / US cơ bản). Hoặc, họ có thể ngừng gửi một lĩnh vực. Hoặc họ có thể thêm một hoặc nhiều lĩnh vực trong tương lai. Bất kỳ sự kết hợp của điều này và những thứ khác. Vậy tại sao chỉ tập trung vào VARCHARcác cột? Điều gì xảy ra nếu họ hiện đang gửi một INTgiá trị và trong một hoặc hai năm họ đạt được giá trị tối đa và bắt đầu gửi một giá trị BIGINT? Điều gì xảy ra nếu họ có trường "trạng thái" có giá trị 0 - 5. Bạn sẽ giả sửINTcái nào được "độn" vì nó cho phép tăng trưởng, nhưng có lẽ nên TINYINT?

Điều duy nhất mà bạn có thể dự đoán một cách an toàn là cố gắng dự đoán dữ liệu khách hàng của bạn sẽ thay đổi như thế nào sẽ sai thường xuyên hơn là chính xác. Và đúng là một vấn đề may mắn / trùng hợp (nếu không may mắn, thì cứ chơi xổ số;).

Vì vậy, hướng dẫn là:

  1. Đừng lãng phí thời gian và năng lượng vào việc cố gắng trả lời một câu hỏi không thể trả lời.
  2. Thay vào đó, hãy tập trung vào việc lấy càng nhiều thông tin càng tốt về dữ liệu thực tế của khách hàng của bạn và đi cùng với điều đó (tức là đưa ra quyết định dựa trên dữ liệu ;-).

Bạn đã có dữ liệu ví dụ, tuyệt vời. Nhưng, đừng quên rằng bạn cũng có thông tin liên hệ của khách hàng: điện thoại và / hoặc email. Liên hệ với chúng! Hỏi họ về thông số dữ liệu của họ (giống như hệ thống của bạn, dữ liệu hiện tại trong hệ thống của họ có thể có độ dài tối đa là 35, nhưng hệ thống của họ có định nghĩa là VARCHAR(50)và hệ thống của họ sẽ chấp nhận đến độ dài đó, trong trường hợp bạn nên sử dụng 50). Và, hỏi họ xem họ có kế hoạch ngắn hạn nào để thay đổi và về các kiểu dữ liệu đó không (loại và / hoặc kích thước).


1
Tôi đồng ý với Solomon, @ Aristotle2600 - tuy nhiên, bạn có thể muốn xem câu trả lời của tôi về một câu hỏi liên quan đến sự khác biệt giữa a varchar(255)và a varchar(256)để xem xét thêm
Max Vernon

Cảm ơn, tôi đã có ấn tượng rằng nó sẽ là một cái gì đó như thế này và "chỉ sử dụng những gì bạn cần" chỉ là thực hành quản lý tài nguyên tốt xung quanh. Tuy nhiên, một số dữ liệu khách hàng của chúng tôi dao động một chút, vì vậy chúng tôi thường làm cho các cột chỉ rộng hơn một chút so với mức cần thiết, lớn hơn 15-20% cho các cột đó. Tôi đã tự hỏi nếu có bất kỳ cân nhắc đặc biệt khác; ví dụ, một người mà tôi làm việc cùng đã bảo tôi sử dụng kích cỡ 2 ^ n - 1 (tôi không tìm thấy bằng chứng nào cho thấy điều đó ....). Nhưng có vẻ như không có gì khác ngoài việc giữ mọi thứ nhỏ nhất có thể.
aristotle2600

1
@ aristotle2600 Không chắc chắn cách áp dụng "2 ^ n - 1", nhưng tôi vẫn phải hỏi: liệu về mặt lý thuyết có thể làm một cái gì đó lớn hơn mức cần thiết không? Không phải kích thước lớn hơn 15-20% sẽ là kích thước mà nó cần phải không bị phá vỡ sao? ;-). Tôi chắc chắn sẽ hữu ích nếu bạn rõ ràng hơn về nguồn dữ liệu, bởi vì a) nếu bạn tạo "URL" 1024 và ai đó cần 1060, thì cần phải là 1060, nhưng b) nếu ai đó muốn thêm 1000 ký tự vào trường nhận xét giới hạn 500 ký tự, sau đó vẫn chỉ cần là 500. Mọi người có thể nhập ít hơn vào nhận xét, nhưng SKU sản phẩm tốt hơn đủ lớn.
Solomon Rutzky

@ aristotle2600 Tôi vừa thêm một số ý kiến ​​của bạn vào câu hỏi vì chúng cung cấp bối cảnh tốt. Tôi cũng đã thêm nội dung vào cuối câu trả lời của mình :)
Solomon Rutzky

Rất cảm ơn cho câu trả lời của bạn! Có, tên và địa chỉ flucinating. Theo như nghịch lý ngày càng tăng 20%, tôi hiểu ý của bạn, nhưng tôi đang nói về việc tạo bảng ban đầu. Một khách hàng sẽ cho chúng tôi biết rằng họ sẽ bắt đầu gửi cho chúng tôi một bảng mới và gửi dữ liệu mẫu (hoặc chỉ là tập dữ liệu sản xuất đầu tiên), chúng tôi xem xét và tạo một bảng ở cuối để giữ dữ liệu. Chúng tôi muốn làm cho bảng cuối cùng của chúng tôi để xử lý nhập khẩu trong tương lai cũng như những gì trong mẫu. Nhưng, một số hàng nhất định bị ràng buộc để có được lâu hơn, vì vậy chúng tôi đệm chúng. Câu hỏi là bao nhiêu, và có hướng dẫn kỹ thuật không?
aristotle2600
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.