2012-05-29 3 views
0

내 웹 응용 프로그램을 사용하면 사용자가 에서 최대 30 개의 전자 메일 (기타 항목 일 수 있음)을 정의 할 수 있습니다. 이 중 어떤 옵션이 가장 좋습니까?MySQL 칼럼 구성

1) ...과 같이, 세퍼레이터를 이용하여 하나의 컬럼의 내부 데이터를 저장 :

  • [칼럼 이메일] 베드로 @ example.com 메리 @ example.com 존 @ 예. COM

구조 : 같이, 별개의 열을 사용

emails VARCHAR(1829)

 

2) ... 또는 저장 데이터 :,745,151

5,

구조 :

email1 VARCHAR(60) 
email2 VARCHAR(60) 
email3 VARCHAR(60) 
[...] 
email30 VARCHAR(60)

미리 감사드립니다.

답변

1

데이터 사용 방법 및 30 분의 고정 양에 따라 다릅니다. WHERE 절 등을 사용하여 세 번째 주소 나 필터를 빠르게 쿼리하는 것이 유리한 경우 : 별개의 필드를 사용하십시오. 그렇지 않으면 열을 작성하는 데 도움이되지 않을 수 있습니다.

데이터베이스에 데이터를 저장하면 여러 사용자가 동시에 액세스 할 수 있다는 장점이 있습니다.

1

2 번이 더 나은 옵션입니다. 첫 번째 파일 (쉼표로 분리)을 수행하면 RDBMS 사용의 이점이 없어집니다 (이 경우 이메일에서 효율적인 쿼리를 실행할 수 없으므로 플랫 파일 일 수 있습니다).

+0

저는 2 번이 좋은 옵션이고, 1 번보다 더 좋은 옵션이 아닐 것이라고 강력히 반대합니다. 응용 프로그램 설계 관점에서 볼 때, 심지어 성능 관점에서 볼 때, 값에 대해 30 개의 다른 열을 검사하는 것은 악몽입니다. – futureal

0

숫자 2가 1보다 낫습니다. 당신이 당신의 사용자 레코드에 foreign key와 별도의 이메일 테이블이 곳

그러나, 당신은 normalized 구조를 얻기의 다른 옵션을 고려해야합니다. 이렇게하면 index을 정의하여 전자 메일로 검색하여 사용자를 찾고 constraint을 입력하면 중복 된 전자 메일이 등록되지 않도록 할 수 있습니다.

0

어느 쪽도 좋은 옵션이 아닙니다.

옵션 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 CASCADEuser 테이블에서 레코드를 삭제하면 관련된 모든 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; 

, 응용 프로그램에 따라, 당신은 할 수 있습니다 전자 메일 열에 인덱스를 추가합니다.

마지막으로 정규화 된 데이터베이스 디자인을 원하지 않는 상황이 있으며, 상황이 극단적으로 적을지라도 구분 된 텍스트가있는 단일 열 디자인이 더 적절할 수 있습니다. 대부분의 일반 응용 프로그램에서 이러한 유형의 정규화 된 디자인은 성능을 향상시키고 확장하는 데 도움이됩니다.