Sử dụng văn bản MAX hoặc cụ thể hơn, loại nhỏ hơn


22

Ai đó đang xem xét mã DDL của tôi để tạo bảng và đề xuất, khi họ thấy tôi thấy sử dụng VARCHAR(256)các trường cho văn bản, tôi sẽ thấy khá nhỏ, như tên hoặc bất cứ thứ gì, mà tôi luôn luôn nên sử dụng VARCHAR(MAX)và liên kết Tại sao nên sử dụng bất cứ thứ gì ngoài varchar (max ) . Tôi đã đọc nó nhưng dường như đã có ngày, vì nó đang tập trung vào năm 2005 và dường như không đưa ra bất kỳ lời biện minh thực sự nào để phân bổ có khả năng lên tới 2 GB mỗi hàng trên tất cả các trường văn bản.

Từ quan điểm về hiệu năng, lưu trữ, v.v., người ta nên đi đến quyết định nên sử dụng VARCHAR(MAX)hay một loại cụ thể nhỏ hơn cho các phiên bản hiện đại của SQL Server? (ví dụ: 2008, 2012, 2014)

Câu trả lời:


31

Tôi có nên luôn luôn sử dụng (n)varchar(max)cho các cột văn bản?

Không.

Đối với SQL Server, các maxloại dữ liệu chỉ nên được chỉ định khi không có sự thay thế. Thay vào đó, người ta nên chọn loại cơ sở chính xác ( varcharhoặc nvarchar) và chỉ định độ dài tối đa rõ ràng phù hợp với dữ liệu sẽ được lưu trữ.

Lưu trữ vật lý là giống hệt nhau cho dù cột được gõ là varchar(n)hay varchar(max), vì vậy đó không phải là mối quan tâm.

Những lý do để không chọn (n)varchar(max)ở mọi nơi xoay quanh các tính năng, chất lượng kế hoạch và hiệu suất.

Một danh sách đầy đủ có lẽ không thực tế, nhưng trong số những thứ khác, maxcác cột:

Tính năng, đặc điểm

  • Yêu cầu một ràng buộc riêng để thực thi độ dài tối đa
  • Không thể là một khóa trong một chỉ mục (vì vậy cũng không có ràng buộc duy nhất nào)
  • Có thể ngăn DDL trực tuyến (bao gồm xây dựng lại chỉ mục và thêm cột không null mới)
  • Nói chung không được hỗ trợ cho các tính năng 'mới hơn', ví dụ: cột
  • Xem tài liệu sản phẩm để biết các tính năng và giới hạn cụ thể hơn. Mô hình chung là có những hạn chế và hạn chế khó xử xung quanh maxcác loại dữ liệu. Không phải tất cả các hạn chế và tác dụng phụ được ghi lại.

Hiệu suất

  • Yêu cầu xử lý đặc biệt trong công cụ thực thi, để tính kích thước rất lớn. Thông thường, điều này liên quan đến việc sử dụng đường dẫn mã kém hiệu quả hơn, với giao diện phát trực tuyến
  • Có thể có các hậu quả không lường trước được tương tự đối với mã bên ngoài (và các thành phần SQL Server khác như SSIS), cũng phải được chuẩn bị để xử lý dữ liệu có kích thước tối đa 2GB
  • Được giả định là rộng 4000 byte trong tính toán cấp bộ nhớ. Điều này có thể dẫn đến việc dự trữ bộ nhớ quá mức, làm hạn chế sự tương tranh và đẩy các trang dữ liệu và chỉ mục có giá trị ra khỏi bộ nhớ đệm
  • Vô hiệu hóa một số tối ưu hóa hiệu suất quan trọng
  • Có thể kéo dài thời gian khóa
  • Có thể ngăn trình tối ưu hóa chọn kế hoạch tìm kiếm (không động)
  • Ngăn chặn các bộ lọc bị đẩy vào quét và tìm kiếm như một phần dư
  • Có thể làm tăng áp lực và sự tranh chấp tempdb (phụ thuộc phiên bản), vì các biến và tham số cũng có khả năng được nhập maxvào để khớp với các định nghĩa cột

Tóm lại, có rất nhiều tác dụng phụ tinh tế (và không mong muốn) của việc sử dụng bộ maxxác định một cách không cần thiết đến mức không có ý nghĩa gì để làm điều này. 'Tiện lợi' nhỏ của việc sử dụng một tuyên bố là không có loại bồi thường.

Đánh giá từng loại trong ngữ cảnh, sử dụng đúng loại cơ sở ( varcharhoặc nvarchar) và độ dài rõ ràng hợp lý.

Đọc thêm:


8

Điều này sẽ đọc giống như câu trả lời của một người hoang tưởng, nhưng không chỉ có những cân nhắc về lưu trữ và hiệu suất.

Bản thân cơ sở dữ liệu không kiểm soát các máy khách của nó và các máy khách không thể được giả định là luôn chèn an toàn đầu vào của người dùng - ngay cả khi cơ sở dữ liệu được thiết kế chỉ được sử dụng với ứng dụng .net sử dụng Entity Framework để đóng gói các giao dịch và đảm bảo các truy vấn được tham số hóa được sử dụng một cách có hệ thống, bạn không thể biết rằng nó sẽ luôn luôn như vậy.

Tôi sẽ không biết chính xác làm thế nào để làm điều này, nhưng bằng cách tạo tất cả các trường văn bản varchar(max), nếu khách hàng có vấn đề về Bảng Bobby và / hoặc các tham số quy trình được lưu trữ của bạn cũng vậy varchar(max), thì bạn sẽ dễ dàng cho kẻ tấn công đến với một giá trị tham số xấu hợp lệ nhưng thông minh có thể làm những việc mà khách hàng không nên làm - bất kể đó là gì.

Bằng cách giới hạn độ dài cho những gì bạn thực sự cần, bạn sẽ không che chắn bản thân khỏi những cuộc tấn công thông minh này (tôi thậm chí không chắc nó thực sự được gọi là gì, tôi chỉ nhớ đọc về nó một lúc trước), nhưng bạn không nói " hãy tiếp tục, cố gắng cho tôi một kịch bản 2GB để chạy ".


Cái mà nó gọi là "tiêm" ("SQL SQL", cụ thể hơn).
Andriy M

@AndriyM yeah, vì một số lý do tôi đã nghĩ đến các cuộc tấn công cắt ngắn SQL (MS dường như đã gỡ bỏ liên kết mà tôi đã đánh dấu), nhưng về cơ bản đó là khai thác varchar(not-max)các tham số, vì vậy tôi bị kẹt một chân ở đây. Nhưng vâng SQL tiêm sẽ được áp dụng ở đây. Có lẽ tôi nên viết lại câu trả lời này một chút.
Mathieu Guindon
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.