2011-10-24 31 views
16

Tôi hiện đang có schema này:MySQL hiệu suất truy vấn tiến thoái lưỡng nan: enum vs bảng

CREATE TABLE `users` (
    `users_id` int(11) NOT NULL AUTO_INCREMENT, 
    `users_name` varchar(50), 
    `users_lastname` varchar(50), 
    `users_dob` date, 
    `users_type` int(11) NOT NULL default 0, 
    `users_access` int(11) NOT NULL default 0, 
    `users_level` int(11) NOT NULL default 0, 
    /* etc...*/ 
    PRIMARY KEY (`users_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

CREATE TABLE `users_types` (
    `types_id` int(11) NOT NULL AUTO_INCREMENT, 
    `types_name` varchar(50), 
    PRIMARY KEY (`types_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

/* etc..*/ 

Query:

SELECT 
    types_name AS user_type, 
    /* all other fields*/ 
    users.* 
    FROM users 
    INNER JOIN users_types ON (users.users_type=types_id); 
    /* INNER JOIN for all other tables*/ 
/* Rest of query */ 

giải pháp mới của tôi:

CREATE TABLE `users` (
    `users_id` int(11) NOT NULL AUTO_INCREMENT, 
    `users_name` varchar(50), 
    `users_lastname` varchar(50), 
    `users_dob` date, 
    `users_type` ENUM('type1', 'type2', 'type3'), 
    `users_access` ENUM('access1', 'access2', 'access3'), 
    `users_level` ENUM('level1', 'level2', 'level3'), 
    /* etc...*/ 
    PRIMARY KEY (`users_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

Query:

SELECT 
    * 
    FROM users 

Từ những gì tôi thấy đang sử dụng ENUM rất đơn giản và có thể rất nhanh để thực thi.

  1. Tôi có đúng không? Nó sẽ nhanh hơn cho Công cụ MySQL để xử lý một trường loại ENUM chứ không phải là LEFT JOINs?
  2. Sử dụng ENUM có thực hành tốt không?

Cảm ơn

+1

Bảng là tốt nếu danh sách enum sẽ được thay đổi. Nó chỉ là một truy vấn chèn/cập nhật đơn giản. Enums sẽ yêu cầu một bảng thay đổi. –

+0

số nguyên đã ký (4 byte) cho các kiểu tra cứu có vẻ hơi quá mức - làm thế nào về tinyints chưa được ký? –

+0

Tôi nên sử dụng int không dấu? Tôi có hơn 200.000 người dùng – Tech4Wilco

Trả lời

19

Cá nhân, tôi nghĩ rằng loại dữ liệu int nên được sử dụng và ENUM-ification của dữ liệu đó nên được thực hiện trong một lớp khác.

Định nghĩa bảng là nơi kém để lưu trữ âm lượng của các giá trị enum của bạn. Thật khó để có được một cách dễ dàng, và cho ứng dụng của bạn sức mạnh để sửa đổi các định nghĩa bảng là một vấn đề an ninh (có thể).

Thay vào đó, tôi khuyên bạn nên sử dụng loại INT và sau đó trong phần mềm của bạn, tạo mô hình tương tác với cơ sở dữ liệu bên dưới để cung cấp sự xuất hiện của ENUM.

Với lựa chọn thiết kế này, chuyển phần mềm cơ sở dữ liệu là tầm thường, bạn không cần cấp đặc quyền "ALTER TABLE" cho ứng dụng sản xuất của bạn và mở rộng enum của bạn thật dễ dàng. Thêm vào đó, bạn sẽ giảm số lần chương trình cần thực hiện bản dịch từ ENUM -> số nguyên - nó có thể được thực hiện tại thời gian biên dịch thay vì với mọi yêu cầu SQL cơ sở dữ liệu.

+0

do đó bạn sẽ có một tệp cho các tùy chọn này trong một tệp riêng biệt và sử dụng chúng như định nghĩa hoặc một cái gì đó, ví dụ: define ('USER_ACCESS_ADMIN', 1) ;? – Tech4Wilco

+0

Vâng, đó là những gì tôi sẽ làm –

+0

cảm ơn thông tin – Tech4Wilco

1

1) Có, nó sẽ nhanh hơn, như datatype ENUM được lập chỉ mục trong bảng riêng của mình (tức là không cần phải đọc bảng khác cho mỗi bản ghi)

2) Có, miễn là bạn không muốn sử dụng các trường đó trong bất kỳ bảng nào khác. Ngay sau khi bạn muốn sử dụng một trường nhất định trong nhiều hơn một bảng, bạn nên tạo một bảng tra cứu riêng cho trường đó. Ngoài ra, nếu bạn muốn trường có các giá trị do người dùng xác định (và không yêu cầu họ sửa đổi cơ sở dữ liệu trực tiếp để thay đổi chúng), bạn nên sử dụng một bảng riêng biệt.

+0

Việc thêm các mục vào một enum không thực sự buộc xây dựng lại bảng, vì vậy nó linh hoạt hơn bạn nghĩ. – Johan

+0

Tôi biết, nó chỉ là một chút đau đớn để duy trì nó khi bạn phải sửa đổi các mục nhập trong information_schema.columns để giữ danh sách ENUM của bạn được cập nhật. – Crontab

+0

Đó là một câu lệnh 'thay đổi bảng thay đổi bảng 'đơn giản, không cần làm rối loạn thông tin trong information_schema. – Johan

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