2015-10-14 28 views
6

Khi thực hiện một INSERT, Redshift không cho phép bạn chèn một giá trị chuỗi dài hơn/rộng hơn trường mục tiêu trong bảng. Quan sát:Redshift: Cắt giá trị VARCHAR tự động trên INSERT hoặc có thể sử dụng độ dài tối đa?

CREATE TEMPORARY TABLE test (col VARCHAR(5)); 
-- result: 'Table test created' 

INSERT INTO test VALUES('abcdefghijkl'); 
-- result: '[Amazon](500310) Invalid operation: value too long for type character varying(5);' 

Một workaround cho điều này là để cast giá trị:

INSERT INTO test VALUES('abcdefghijkl'::VARCHAR(5)); 
-- result: 'INSERT INTO test successful, 1 row affected' 

Phần khó chịu về việc này là bây giờ tất cả các mã của tôi sẽ phải có những tuyên bố dàn diễn viên trên mỗi INSERT cho mỗi Trường VARCHAR như thế này, hoặc mã ứng dụng sẽ phải cắt bớt chuỗi trước khi cố gắng xây dựng truy vấn; một trong hai cách, nó có nghĩa là đặc tả chiều rộng của cột phải đi vào mã ứng dụng, điều này gây phiền toái.

Có cách nào tốt hơn để thực hiện việc này bằng tính năng Redshift không? Nó sẽ là tuyệt vời nếu có một số tùy chọn để chỉ có máy chủ cắt ngắn chuỗi và thực hiện (và có thể nâng cao một cảnh báo) cách nó với MySQL.

Một điều tôi có thể làm là chỉ khai báo các trường cụ thể này dưới dạng VARCHAR rất lớn, có lẽ thậm chí là 65535 (mức tối đa).

create table analytics.testShort (a varchar(3)); 
create table analytics.testLong (a varchar(4096)); 
create table analytics.testSuperLong (a varchar(65535)); 

insert into analytics.testShort values('abc'); 
insert into analytics.testLong values('abc'); 
insert into analytics.testSuperLong values('abc'); 

-- Redshift reports the size for each table is the same, 4 mb 

Một nhược điểm của phương pháp này tôi đã tìm thấy là nó sẽ gây ra hiệu suất kém nếu cột này được sử dụng trong một nhóm bằng/join/etc:

https://discourse.looker.com/t/troubleshooting-redshift-performance-extensive-guide/326 (tìm kiếm VARCHAR)

Tôi tự hỏi rằng nếu không có hại gì khác nếu bạn dự định không bao giờ sử dụng trường này theo nhóm, tham gia và tương tự.

Một số điều cần lưu ý trong kịch bản của tôi: Có, tôi thực sự không quan tâm đến các ký tự thừa có thể bị mất khi cắt, và không, tôi không có cách nào để thực thi độ dài của văn bản gốc. Tôi đang chụp thư và URL từ các nguồn bên ngoài thường nằm trong phạm vi nhất định về độ dài ký tự, nhưng đôi khi có các ký tự dài hơn. Nó không quan trọng trong ứng dụng của chúng tôi nếu chúng bị cắt bớt hoặc không được lưu trữ.

Trả lời

6

Cách duy nhất để tự động cắt các dây để phù hợp với chiều rộng cột được sử dụng lệnh COPY với các tùy chọn TRUNCATECOLUMNS

truncates dữ liệu trong các cột với số thích hợp của các nhân vật rất rằng nó phù hợp với các đặc điểm kỹ thuật cột . Chỉ áp dụng cho các cột có loại dữ liệu VARCHAR hoặc CHAR và các hàng có kích thước từ 4 MB trở xuống.

Nếu không, bạn sẽ phải chăm sóc theo chiều dài của chuỗi bằng cách sử dụng một trong hai phương pháp:

  1. Rõ ràng CAST giá trị của bạn đến VARCHAR bạn muốn:

    INSERT INTO test VALUES(CAST('abcdefghijkl' AS VARCHAR(5)));

  2. Sử dụng các chức năng chuỗi LEFT and RIGHT để cắt ngắn chuỗi của bạn:

    INSERT INTO test VALUES(LEFT('abcdefghijkl', 5));

+0

Cảm ơn, vâng, đây là những gì chúng tôi đã giải quyết từ lâu. Đối với chèn số lượng lớn lớn, chúng tôi đang sử dụng tùy chọn cắt ngắn cho COPY, điều này khá rõ ràng. Đối với các hoạt động INSERT và UPDATE khác được thực hiện ở nơi khác, chúng tôi đang thực hiện CAST bằng toán tử '::'. – olanmills

Các vấn đề liên quan