2011-10-24 3 views
16

나는 현재이 스키마가 있습니다MySQL의 쿼리 성능 딜레마 : 테이블 대 열거

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..*/ 

검색어 :

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 */ 

내 새로운 솔루션 :

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; 

검색어 :

SELECT 
    * 
    FROM users 

내가보기에 ENUM을 사용하면 매우 간단하고 실행할 수 있습니다.

  1. 맞습니까? LEFT JOIN보다 ENUM 타입 필드를 처리하는 것이 MySQL 엔진에 더 빠르지 않습니까?
  2. ENUM을 사용하고 있습니까? 상기 ENUM 데이터 타입이 테이블 자체에 각 레코드에 대해 다른 테이블을 읽을 수있는 (즉 필요)

    2) 예를 인덱싱하지로

감사

+1

열거 형 목록이 변경되면 테이블이 적합합니다. 그것은 단지 간단한 삽입/업데이트 쿼리 일뿐입니다. 열거 형에는 alter table이 필요합니다. –

+0

조회 유형에 대한 부호있는 정수 (4 바이트)가 약간 과장된 것처럼 보입니다 - 부호없는 tinyints는 어떻습니까? –

+0

부호없는 int를 사용해야합니까? 200,000 명이 넘는 사용자가 있습니다 – Tech4Wilco

답변

19

개인적으로 int 데이터 형식을 사용해야하며 해당 데이터의 ENUM 작성은 다른 계층에서 수행되어야한다고 생각합니다.

테이블 정의는 열거 형 값의 영역을 저장하기에 좋지 않습니다. 쉽게 얻을 수 없으며 응용 프로그램에 테이블 정의를 수정할 수있는 권한을 부여하는 것이 보안 문제 (가능하면)입니다.

대신 INT 유형을 사용하고 소프트웨어에서 ENUM의 모양을 나타 내기 위해 아래 데이터베이스와 상호 작용하는 모델을 만드는 것이 좋습니다.

이 디자인을 선택하면 데이터베이스 소프트웨어를 전환하는 것이 쉽지 않으므로 프로덕션 응용 프로그램에 "ALTER TABLE"권한을 부여 할 필요가 없으며 열거 형 확장이 쉽습니다. 또한, 프로그램이 ENUM -> integer로부터 변환을 수행해야하는 횟수를 줄이고 있습니다. 이는 모든 데이터베이스 SQL 요청 대신 컴파일 타임에 수행 할 수 있습니다.

+0

그래서이 옵션에 대한 파일을 별도의 파일에 가지고 있으며이를 define 또는 something으로 사용합니다 : define ('USER_ACCESS_ADMIN', 1) ;? – Tech4Wilco

+0

예, 그게 내가 할 일이야 –

+0

정보 주셔서 감사합니다 – Tech4Wilco

1

1) 네,,, 빠른 것 다른 테이블에서 해당 필드를 사용하지 않으려는 경우에만 가능합니다. 하나 이상의 테이블에서 주어진 필드를 사용하고자 할 때, 해당 필드에 대해 별도의 찾아보기 테이블을 생성해야합니다. 또한 필드에 사용자가 정의 할 수있는 값을 지정하고 변경할 필드를 직접 수정할 필요가없는 경우에는 별도의 테이블을 사용해야합니다.

+0

열거에 항목을 추가해도 실제로 테이블이 다시 작성되지는 않으므로 생각보다 유연합니다. – Johan

+0

ENUM 목록을 최신 상태로 유지하려면 information_schema.columns의 항목을 수정해야 할 때 유지 보수하는 것이 조금은 고통 스럽습니다. – Crontab

+0

이것은 간단한'alter table change column' 명령문으로, 필요한 information_schema에 관한 내용이 없습니다. – Johan