Có thể thay đổi danh sách ENUM () không?


19

Tôi không chắc chắn nếu thay đổi danh sách ENUM () là không thể nên tôi đã thực hiện một bài kiểm tra. Trong MySQL v5.1.58, tôi đã tạo một bảng InnoDB thử nghiệm có chứa một trường gọi là 'bool' loại ENUM ('có', 'không').

Sau đó, tôi đã thực hiện ...

ALTER TABLE  `test`
CHANGE  `bool`  `bool` ENUM(  'yes',  'no',  'maybe' )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL

...va no đa hoạt động.

Tôi đã làm gì sai? Có phụ thuộc vào công cụ db không?
Tại sao mọi người nói thay đổi danh sách ENUM () là không thể? ví dụ. tại đây http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/


3
Bài báo bạn đề cập không nói là không thể; Nó nói rằng việc thay đổi danh sách thành viên là tốn kém vì công cụ quét toàn bộ bảng.
a1ex07

Tôi đã đề cập liên kết của bạn trở lại vào tháng 10 về ENUMs ( dba.stackexchange.com/a/6966/877 ). Ngoài ra, tôi đã đăng một tài liệu tham khảo về cách thực hiện điều này trong MyISAM ( dba.stackexchange.com/a/6548/877 ). InnoDB là ra khỏi câu hỏi trong trường hợp này.
RolandoMySQLDBA

Câu trả lời:


14

Miễn là bàn trống, không có vấn đề gì. Miễn là các giá trị mới cho ENUM được nối thêm và không được đổi tên thành một bảng được điền, một lần nữa không có vấn đề gì.

ENUM mà bạn xác định lại trong câu hỏi của bạn thực sự giữ các giá trị bên trong ban đầu là có và không như bảng thử nghiệm đã ghi nhớ lần cuối.

Những điều sau đây áp dụng cho các bảng dân cư:

Cái này thì sao?

ALTER TABLE  `test`
CHANGE  `bool`  `bool` ENUM(  'no',  'yes',  'maybe' )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL

Bây giờ bạn có một vấn đề. Các giá trị ENUM trong một bảng được điền đầy đủ sẽ có các giá trị bên trong của chúng được đảo ngược để có ngay bây giờ là không và bây giờ là có.

Cái này thì sao?

ALTER TABLE  `test`
CHANGE  `bool`  `bool` ENUM(  'maybe', 'no',  'yes' )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL

Vấn đề lớn. Trong một bảng dân cư, có thể bây giờ có thể. Các hàng mới được chèn với yes bị ngắt kết nối với các hàng yes trước đó bởi vì bây giờ chúng có thể có nghĩa.

TÓM LƯỢC

Có những kỹ thuật mồi và chuyển đổi có rủi ro rất cao để thực hiện việc này rất nhanh trong MyISAM . Tôi thực sự khuyên bạn không nên làm điều này trong InnoDB vì tương tác id không gian bảng của nó với ibdata1.


Vì vậy, bên trong chúng được lưu trữ dưới dạng int dựa trên thứ tự trong ENUM (). Ví dụ: ENUM ('có', 'không', 'có thể') lưu trữ nội bộ 0 cho 'có', 1 cho 'không', 2 ​​cho 'có thể'. Tôi tưởng tượng rằng siêu dữ liệu của bảng giống như ENUM ('có', 'không', 'có thể') thay vì ENUM ('có' => 0, 'không' => 1, 'có thể' => 2). Có thật không?
Aalex Gabi

ENUM là các chuỗi không phải là số nguyên: dev.mysql.com/doc/refman/5.0/en/enum.html
RolandoMyQueryDBA

Tôi đồng ý ENUM là các chuỗi nhưng bên trong chúng không được lưu trữ dưới dạng chuỗi phải không?
Aalex Gabi

1
Bạn đúng trong việc này. Trong liên kết tôi cung cấp, có một ánh xạ của chuỗi thành số nguyên dưới dạng siêu dữ liệu. Tìm cụm từ này: For example, a column specified as ENUM('one', 'two', 'three') can have any of the values shown here. The index of each value is also shown.và bản đồ giá trị / chỉ mục được khái niệm hóa. Do đó, sẽ có một giá trị ENUM trong một bảng được liên kết với số chỉ mục nội bộ. Sắp xếp lại các chuỗi sẽ sắp xếp lại chỉ mục siêu dữ liệu. Điều này không tốt cho bảng dân cư khi xác định lại ENUM.
RolandoMySQLDBA

2
Ít nhất là đối với MariaDB / InnoDB, tôi có thể nói điều này không còn hợp lệ nữa. Thay đổi giữa ENUM, miễn là không có bản ghi nào với các giá trị bị xóa / thay đổi, các giá trị khác sẽ được giữ nguyên. Ưu điểm duy nhất là nó phải xây dựng lại bảng.
Nuno
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.