어느 쪽도 좋은 옵션이 아닙니다.
옵션 1은 전자 메일로 사용자를 복잡하고 비효율적 인 작업으로 보게하기 때문에 좋지 않습니다. 하나의 전자 메일을 찾으려면 사용자 레코드의 전자 메일 필드에서 전체 텍스트 검색을 수행해야합니다.
옵션 2는 주위의 코드를 작성하는 데 엄청난 고통을주기 때문에 실제로는 매우 이상한 아이디어 인 IMO입니다. 다시 X 값을 가진 모든 사용자를 찾아야한다고 가정하십시오. 이제 30 개의 열을 열거하고 각 열을 확인하여 해당 값이 존재하는지 확인해야합니다. 아픈!
데이터의 일부 요소 중 일부 또는 그 이상은 데이터베이스 디자인에서 매우 일반적이며, 앞서 언급 한 것처럼 Adam은 정규화 된 데이터 구조를 사용하여 대부분의 경우에 가장 잘 해결됩니다.
사용자 테이블 :
CREATE TABLE user (
user_id int auto_increment,
...
PRIMARY KEY (user_id)
);
이메일 테이블 :
CREATE TABLE user_email (
user_id int,
email char(60) not null default '',
FOREIGN KEY (user_id) REFERENCES user (user_id) ON DELETE CASCADE
);
FOREIGN KEY
문
이이 같은 태그 이후의 MySQL로 작성된 올바른 테이블 구조,처럼 보일 수 있습니다 선택 사항이다 - 디자인은 그것 없이는 작동하지만, 그 라인은 데이터베이스가 관계를 강제하게 만든다. 예를 들어 user_id
이 10 인 user_email
에 레코드를 삽입하려고 시도하면 user_id
이 10 인 해당 user
레코드가 있어야합니다. 그렇지 않으면 쿼리가 실패합니다. ON DELETE CASCADE
은 user
테이블에서 레코드를 삭제하면 관련된 모든 user_email
레코드도 삭제됩니다 (이 동작을 원하지 않을 수도 있음)는 데이터베이스에 알려줍니다.
물론이 디자인은 사용자 레코드를 검색 할 때 조인을 수행해야한다는 것을 의미합니다. 이 같은 쿼리 :
SELECT user.user_id, user_email.email FROM user LEFT JOIN user_email ON user.user_id = user_email.user_id WHERE <your where clause>;
시스템에 저장된 각 USER_EMAIL 주소에 대해 하나 개의 행을 반환합니다. 사용자가 5 명이고 각 사용자의 이메일 주소가 5 개인 경우 위 쿼리는 25 개의 행을 반환합니다.
응용 프로그램에 따라 사용자 당 하나의 행을 가져오고 모든 전자 메일에 계속 액세스 할 수 있습니다. 이 경우 해당 사용자에 속하는 이메일의 쉼표로 구분 된 목록으로, 사용자 당 하나의 행을 반환합니다 GROUP_CONCAT
같은 집계 함수를 시도 할 수 있습니다 : 다시
SELECT user.user_id, GROUP_CONCAT(user_email.email) AS user_emails FROM user LEFT JOIN user_email ON user.user_id = user_email.user_id WHERE <your where clause> GROUP BY user.user_id;
, 응용 프로그램에 따라, 당신은 할 수 있습니다 전자 메일 열에 인덱스를 추가합니다.
마지막으로 정규화 된 데이터베이스 디자인을 원하지 않는 상황이 있으며, 상황이 극단적으로 적을지라도 구분 된 텍스트가있는 단일 열 디자인이 더 적절할 수 있습니다. 대부분의 일반 응용 프로그램에서 이러한 유형의 정규화 된 디자인은 성능을 향상시키고 확장하는 데 도움이됩니다.
저는 2 번이 좋은 옵션이고, 1 번보다 더 좋은 옵션이 아닐 것이라고 강력히 반대합니다. 응용 프로그램 설계 관점에서 볼 때, 심지어 성능 관점에서 볼 때, 값에 대해 30 개의 다른 열을 검사하는 것은 악몽입니다. – futureal