Mã lỗi 1117 Quá nhiều cột; Giới hạn cột của MySQL trên bảng


37

Tôi có một bảng có 1699 cột và khi tôi cố gắng chèn thêm các cột tôi nhận được,

Mã lỗi: 1117. Quá nhiều cột

Trong bảng này tôi chỉ có 1000 hàng. Đối với tôi điều quan trọng nhất là số lượng cột. Có bất kỳ hạn chế trên bàn? Tôi muốn tạo 2000 cột. Điều đó có thể không?


21
Chúa ơi, cái quái gì thế. Điều này có mùi giống như một thiết kế cơ sở dữ liệu cực kỳ nghèo nàn. Hoặc có lẽ bạn đang sử dụng công cụ sai cho công việc. Có lẽ bạn nên xem xét chuẩn hóa cơ sở dữ liệu
Zoredache

12
Xoay màn hình của bạn 90 độ. Nghiêm trọng hơn, MySQL (hoặc gần như bất kỳ RDBMS nào khác) không được thiết kế cho THAT nhiều cột.

11
Và tại sao 2000 cảm biến dẫn đến 2000 cột? Thiết kế lại cơ sở dữ liệu của bạn. Tạo một bảng cảm biến riêng biệt hoặc một cái gì đó, nhưng KHÔNG thêm mỗi cảm biến dưới dạng một cột mới. Đó là điều sai lầm không thể tin được để làm.

6
Số bảng tối đa ... whoa đó! Bạn có thể sẽ chỉ cần vài bàn. Thậm chí đừng xem xét việc tạo 2000 bảng thay vì 2000 cột!

2
Xin vui lòng, xin vui lòng đọc về Bình thường hóa cơ sở dữ liệu !

Câu trả lời:


35

Tại sao bạn cần tạo một bảng có 20 cột, chưa kể 2000 ???

Dữ liệu được cấp, không chuẩn hóa có thể ngăn không phải thực hiện THAM GIA để truy xuất nhiều cột dữ liệu. Tuy nhiên, nếu bạn có hơn 10 cột, bạn nên dừng lại và suy nghĩ về những gì sẽ xảy ra dưới mui xe trong quá trình truy xuất dữ liệu.

Nếu một bảng cột 2000 trải qua CHỌN * TỪ ... Ở ĐÂU, bạn sẽ tạo các bảng tạm thời lớn trong quá trình xử lý, tìm nạp các cột không cần thiết và tạo nhiều kịch bản trong đó các gói truyền thông ( max_allowed_packet ) sẽ được đẩy đến bờ vực trên mỗi truy vấn.

Trong những ngày đầu làm nhà phát triển, tôi đã làm việc tại một công ty vào năm 1995, nơi mà DB2 là RDBMS chính. Công ty có một bảng duy nhất có 270 cột, hàng chục chỉ mục và có vấn đề về hiệu năng khi lấy dữ liệu. Họ đã liên hệ với IBM và nhờ các chuyên gia tư vấn xem xét kiến ​​trúc của hệ thống của họ, bao gồm cả bảng nguyên khối này. Công ty được thông báo "Nếu bạn không bình thường hóa bảng này trong 2 năm tới, thì DB2 sẽ thất bại đối với các truy vấn đang thực hiện Xử lý Giai đoạn 2 (mọi truy vấn yêu cầu sắp xếp trên các cột không được lập chỉ mục)." Điều này đã được nói với một công ty trị giá hàng nghìn tỷ đô la, để bình thường hóa một bảng 270 cột. Làm thế nào nhiều hơn một bảng cột 2000.

Về mặt mysql, bạn sẽ phải bù đắp cho thiết kế tồi tệ đó bằng cách đặt các tùy chọn có thể so sánh với Xử lý Giai đoạn 2 của DB2. Trong trường hợp này, những lựa chọn đó sẽ là

Tweeking các cài đặt này để bù cho sự hiện diện của hàng tá, chứ chưa nói đến hàng trăm cột hoạt động tốt nếu bạn có TB RAM.

Vấn đề này nhân lên về mặt hình học nếu bạn sử dụng InnoDB vì bạn sẽ phải đối phó với MVCC (Điều khiển đồng thời đa biến) cố gắng bảo vệ hàng tấn cột với mỗi CHỌN, CẬP NHẬT và XÓA thông qua cách ly giao dịch.

PHẦN KẾT LUẬN

Không có sự thay thế hoặc hỗ trợ ban nhạc có thể bù đắp cho thiết kế xấu. Xin vui lòng, vì sự tỉnh táo của bạn trong tương lai, hãy bình thường hóa bảng đó ngay hôm nay !!!


1
Tôi có thể hình dung công ty sẽ làm thế nào khi nói điều này. Họ thêm móc svn hoặc tạo "Hướng dẫn thực hành tốt nhất DB" yêu cầu nhà phát triển không sắp xếp các cột không được lập chỉ mục trong SQL. Thay vào đó, họ thực hiện sắp xếp trong ứng dụng bằng cách thực hiện thuật toán sắp xếp dữ liệu lớn của riêng họ.
Gqqnbig

25

Tôi gặp khó khăn khi tưởng tượng bất cứ điều gì mà mô hình dữ liệu có thể chứa 2000 cột trong một bảng được chuẩn hóa đúng cách.

Tôi đoán là bạn có thể đang thực hiện một số loại lược đồ không chuẩn hóa "điền vào chỗ trống", trong đó bạn thực sự lưu trữ tất cả các loại dữ liệu khác nhau trong một bảng và thay vì chia dữ liệu ra các bảng riêng biệt và tạo quan hệ , bạn đã có nhiều trường khác nhau ghi lại "loại" dữ liệu nào được lưu trữ trong một hàng nhất định và 90% các trường của bạn là NULL. Mặc dù sau đó, mặc dù, muốn có tới 2000 cột ...

Giải pháp cho vấn đề của bạn là suy nghĩ lại về mô hình dữ liệu của bạn. Nếu bạn đang lưu trữ một đống dữ liệu khóa / giá trị lớn liên quan đến một bản ghi nhất định, tại sao không mô hình hóa nó theo cách đó? Cái gì đó như:

CREATE TABLE master (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields that really do relate to the
    master records on a 1-to-1 basis>
);

CREATE TABLE sensor_readings (
    id INT PRIMARY KEY AUTO_INCREMENT,
    master_id INT NOT NULL,   -- The id of the record in the
                              -- master table this field belongs to
    sensor_id INT NOT NULL,
    value VARCHAR(255)
);

CREATE TABLE sensors (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields relating to sensors>
);

Sau đó, để có được tất cả các mục cảm biến được liên kết với một bản ghi "chính" nhất định, bạn có thể chỉ cần SELECT sensor_id,value FROM sensor_readings WHERE master_id=<some master ID>. Nếu bạn cần lấy dữ liệu cho một bản ghi trong masterbảng cùng với tất cả dữ liệu cảm biến cho bản ghi đó, bạn có thể sử dụng phép nối:

SELECT master.*,sensor_readings.sensor_id,sensor_readings.value
FROM master INNER JOIN sensor_readings on master.id=sensor_readings.master_id
WHERE master.id=<some ID>

Và sau đó tham gia thêm nếu bạn cần chi tiết về từng cảm biến.


18

Đó là một hệ thống đo lường với 2000 cảm biến

Bỏ qua tất cả các ý kiến ​​hét lên về việc chuẩn hóa - những gì bạn đang yêu cầu có thể là thiết kế cơ sở dữ liệu hợp lý (trong một thế giới lý tưởng) và được chuẩn hóa hoàn toàn tốt, nó rất khác thường và như đã chỉ ra ở những RDBMS khác thường không được thiết kế cho nhiều cột này .

Mặc dù bạn không đạt đến giới hạn cứng của MySQL , một trong những yếu tố khác được đề cập trong liên kết có thể ngăn bạn tiến lên cao hơn

Như những người khác đề xuất, bạn có thể giải quyết giới hạn này bằng cách có một bảng con id, sensor_id, sensor_value, hoặc đơn giản hơn, bạn có thể tạo một bảng thứ hai để chỉ chứa các cột không khớp với đầu tiên (và sử dụng cùng một PK)


1
Đây là sự thật. Khi xử lý dữ liệu và SQL tương ứng một cách cẩn thận, câu trả lời của bạn còn nổi bật hơn nữa !!!
RolandoMySQLDBA

3
Sử dụng bảng con không phải là "cách giải quyết". Có một cột cho mỗi cảm biến chỉ đơn giản là thiết kế xấu (sai). Điều đó giống như có một cột cho mỗi nhân viên trong hệ thống nhân sự hoặc một cột cho mỗi nhà sản xuất ô tô cho DB quản lý các mẫu xe hơi.
a_horse_with_no_name

11
@a_horse - bạn đang đưa ra các giả định mà tôi nghi ngờ là hợp lệ. Hoàn toàn có khả năng số lượng cảm biến về cơ bản là cố định, tất cả đều được đọc đồng thời và tất cả đều trả về dữ liệu mỗi lần. Trong trường hợp một cột trên mỗi cảm biến không "sai", chỉ đơn thuần là không thực tế với các giới hạn của cơ sở dữ liệu. Tôi muốn cho rằng những người hỏi không phải là những kẻ ngốc cho đến khi được chứng minh khác đi và iUngi đã trả lời một cách đàng hoàng trước những phản ứng rất không có ích từ đám đông SF.
Jack Douglas

2
@Jack Douglas: ngay cả khi tất cả các giả định của bạn là đúng (mà tôi rất nghi ngờ) việc lưu trữ từng giá trị cảm biến trong cột riêng của nó sẽ gây rắc rối về lâu dài. Còn các truy vấn như "giá trị trung bình của các cảm biến 10 đến 50 và 25 đến 100 giữa ngày hôm qua và hôm nay" thì sao? hoặc "Cảm biến nào có giá trị đọc cao nhất vào thứ hai tuần trước?". Cố gắng viết truy vấn cho điều này với 2000 cột. Sử dụng bảng được chuẩn hóa sẽ giải quyết được nhiều vấn đề hơn về lâu dài so với giải pháp 2000 cột sẽ giải quyết ngay bây giờ.
a_horse_with_no_name

2
Chắc chắn, nếu các cảm biến đang lưu trữ các giá trị liên quan - tôi cho rằng chúng không liên quan (ví dụ: tất cả chúng đều đo các loại khác nhau chứ không phải là cùng một thứ ở các vị trí khác nhau). Bạn có thể nghi ngờ điều đó nhưng chỉ OP biết chắc chắn - và không phải là không thể trong các lĩnh vực y tế hoặc khoa học.
Jack Douglas

15

Giới hạn đếm cột của MySQL 5.0 (nhấn mạnh thêm):

Có giới hạn cứng là 4096 cột trên mỗi bảng , nhưng mức tối đa hiệu quả có thể ít hơn cho một bảng nhất định. Giới hạn chính xác phụ thuộc vào một số yếu tố tương tác.

  • Mỗi bảng (không phân biệt công cụ lưu trữ) có kích thước hàng tối đa là 65.535 byte. Công cụ lưu trữ có thể đặt các ràng buộc bổ sung trên giới hạn này, làm giảm kích thước hàng tối đa hiệu quả.

    Kích thước hàng tối đa ràng buộc số lượng (và có thể kích thước) của các cột vì tổng chiều dài của tất cả các cột không thể vượt quá kích thước này.

...

Các công cụ lưu trữ riêng lẻ có thể áp đặt các hạn chế bổ sung làm hạn chế số lượng cột trong bảng. Ví dụ:

  • InnoDB cho phép lên tới 1000 cột.

7

Đầu tiên là một vài ngọn lửa, sau đó là một giải pháp thực sự ...

Tôi chủ yếu đồng ý với ngọn lửa đã ném vào bạn.

Tôi không đồng ý với chuẩn hóa khóa-giá trị. Truy vấn cuối cùng là khủng khiếp; hiệu suất thậm chí còn tồi tệ hơn.

Một cách 'đơn giản' để tránh sự cố tức thời (giới hạn số lượng cột) là 'phân vùng theo chiều dọc' dữ liệu. Có, nói, 5 bảng với 400 cột mỗi. Tất cả chúng đều có cùng khóa chính, ngoại trừ một khóa có thể là AUTO_INCREMENT.

Có lẽ tốt hơn là quyết định hàng tá lĩnh vực quan trọng nhất, đặt chúng vào bảng 'chính'. Sau đó nhóm các cảm biến theo một cách hợp lý và đặt chúng vào một số bảng song song. Với việc phân nhóm thích hợp, bạn có thể không phải THAM GIA tất cả các bảng mọi lúc.

Bạn đang lập chỉ mục bất kỳ giá trị? Bạn có cần phải tìm kiếm trên chúng? Có lẽ bạn tìm kiếm trên datetime?

Nếu bạn cần lập chỉ mục nhiều cột - punt.

Nếu bạn cần lập chỉ mục một vài - hãy đặt chúng vào 'bảng chính.

Đây là giải pháp thực sự (nếu áp dụng) ...

Nếu bạn không cần một loạt các cảm biến được lập chỉ mục, thì đừng tạo cột! Vâng, bạn đã nghe tôi. Thay vào đó, hãy thu thập chúng vào JSON, nén JSON, lưu trữ nó vào trường BLOB. Bạn sẽ tiết kiệm được một tấn không gian; bạn sẽ chỉ có một bảng, không có vấn đề giới hạn cột; v.v. Ứng dụng của bạn sẽ giải nén và sau đó sử dụng JSON làm cấu trúc. Đoán xem cái gì? Bạn có thể có cấu trúc - bạn có thể nhóm các cảm biến thành các mảng, công cụ đa cấp, v.v., giống như ứng dụng của bạn muốn. Một "tính năng" khác - đó là kết thúc mở. Nếu bạn thêm nhiều cảm biến, bạn không cần THAY ĐỔI bảng. JSON nếu linh hoạt theo cách đó.

(Nén là tùy chọn; nếu tập dữ liệu của bạn rất lớn, nó sẽ giúp dung lượng đĩa, do đó hiệu suất tổng thể.)


Đây là câu trả lời tốt nhất thực tế. Bạn có thể bình luận rằng có lẽ anh ta nên nghiên cứu không có nhiều cột như vậy, nhưng câu trả lời được chấp nhận là 'đừng làm điều đó' không trả lời câu hỏi. Ngay cả khi anh chàng này không thực sự cần nhiều cột như vậy, có thể người khác tìm thấy Q này cũng cần nhiều cột đó và cần một câu trả lời thực sự.
BoB3K

@ BoB3K - Đoạn văn lớn của tôi nói phải làm gì , cung cấp thông tin có sẵn về vấn đề như đã nêu. JSONtránh "quá nhiều cột"; lập chỉ mục các cột được chọn giúp với hiệu suất.
Rick James

3

Tôi thấy đây là một tình huống có thể xảy ra trong thế giới dữ liệu lớn, nơi bạn có thể không thực hiện kiểu truy vấn chọn * truyền thống. Chúng tôi giải quyết vấn đề này trong thế giới mô hình dự đoán ở cấp độ khách hàng nơi chúng tôi mô hình hóa một khách hàng qua hàng ngàn thứ nguyên (tất cả chúng đều có giá trị 0 hoặc 1). Cách lưu trữ này làm cho các hoạt động xây dựng mô hình hạ nguồn trở nên dễ dàng hơn khi bạn có các yếu tố rủi ro trong cùng một hàng và cờ kết quả trong cùng một hàng .. Điều này có thể được chuẩn hóa từ điểm lưu trữ với cấu trúc con cha mẹ, nhưng mô hình dự đoán xuôi dòng sẽ cần chuyển đổi nó trở lại thành lược đồ phẳng. Chúng tôi sử dụng dịch chuyển đỏ, lưu trữ cột, vì vậy hơn 1000 cột của bạn khi bạn tải dữ liệu, thực sự được lưu trữ ở định dạng cột ...

Có một thời gian và địa điểm cho thiết kế này. Chắc chắn rồi. Bình thường hóa không phải là giải pháp cho mọi vấn đề.


Cảm ơn các bình luận. Nếu một người muốn thực hiện phân tích với hình ảnh, ngay cả một hình ảnh màu 16x16 pixel nhỏ cũng cần có số nguyên 16 * 16 * 3 trong khoảng từ 0 đến 255 (3 số để mô tả màu trong một trong số 16x16 pixel sử dụng màu RGB). Đó là 768 cột chỉ dành cho dữ liệu, mà người ta sẽ cần thêm khóa.
VictorZurkowski
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.