2011-02-03 5 views
1

가 나는 테이블은 각 사용자가 다음과 같은 필드가 그 '식물'이라는 테이블에 자신의 공장을 절약 할 수 있습니다 같은MySQL 테이블을 설정하는 가장 효율적인 방법은 무엇입니까?

username 
DOB 
gender 
etc 

으로 필드를 포함 '사용자'라는 한

username 
plant 

그래서 사용자 JohnDoe에 다음과 같이 '식물'테이블에 표시 할 '

johndoe -> lilly 
johndoe -> orchid1 
johndoe -> orchid2 
johndoe -> fern1 
johndoe -> fern2 

질문 :

,

이것은 테이블을 설정하는 나쁜 방법입니까? 사용자 수가 증가하면 수백 개의 행이 생기고 각 사용자마다 둘 이상의 플랜트가 있기 때문에 반복되는 사용자 이름으로 여러 행이 표시되기 때문에 질문합니다. 이 쿼리가 느려 집니까?

사용자 당 플랜트 테이블을 하나 만들면 DB 요청 수가 극적으로 증가하고 DB에 엄청난 테이블이 생성 될 것이라고 생각합니다.

또 다른 옵션은

username 

등의 분야와 등 릴리, 난초, 고사리, 별도의 테이블을 가지고하는 것입니다하지만 난 여전히 반복되는 사용자 이름을 가진 여러 행이있을 것입니다.

제안 사항?

답변

1

대신 사용자 이름을 사용하는 대신 INT ID를 사용합니다. 그래서 같이 :

plantid 
userid_fk 
plantname 

그리고 다음 경기 :

+0

이유가 있습니까? 이것은 정상적인 형태의 데이터베이스를 파괴하는 것으로 보입니다. – symcbean

+0

@symcbean 무엇이 잘못 되었습니까? 내가 사용하는 많은 데이터베이스처럼 보입니다. – gnur

+0

플랜트 테이블에서 _fk 접미어를 userid에 제안하는 이유는 무엇입니까? – pepe

2

테이블을 표준화하십시오. 사용자에게 id 필드를 추가하고 해당 ID를 사용자 이름 대신 식물에 저장하십시오.

자세한 내용은 normalization principles을 읽고 실제로 적용 해보십시오.

+0

(-0.5 minor nit) 당신이 제안하는 것은 정규화가 아니라 확장성에 대한 좋은 습관입니다. – payne

+0

댓글을 달기 전에 일반적인 양식을 읽어보십시오. 명백히 말하자면 두 테이블이 동일한 데이터를 반복하지 않을 수 있습니다. – raveren

+0

나는 물론했다. 그의 사용자 이름/시스템 테이블은 이미 첫 번째 정규 형식입니다. – payne

0

그건 완전히 합리적인 방법입니다 (초기 제안서). 그것은 relational databases을위한 것입니다.

식물 테이블에서 다 대다 관계를 수행하고 있습니다. 각 사용자는 여러 플랜트를 가질 수 있으며 각 플랜트에는 여러 사용자가있을 수 있습니다.

효율성을 높이기 위해 id을 사용하여 사용자 이름 대신 사용자를 참조 할 수 있습니다. 대부분의 관계형 데이터베이스에서 id은 행 번호이며 매우 효율적이며 컴팩트 한 참조입니다.

+0

아니요 - 일대 다 관계 – symcbean

0

을 여기에 대한 가고 싶어 방법은 찾을 users.userid = plants.userid_fk에 가입 :

userid 
username 
DOB 
gender 
etc 

과 식물

이 예제 데이터베이스 스크립트 및 쿼리 :

사용자 만들기 /로드 사용자 테이블 대신 대리자 기본 키를 사용하기 때문에 쿼리가 INTs에 대해 더 빠를 것이고 그들은 아마도 변경 될 수 있습니다 .

CREATE TABLE users ( 
    id   int(11) AUTO_INCREMENT NOT NULL, 
    username varchar(255) NOT NULL, 
    gender  char(1) NULL, 
    PRIMARY KEY(id) 
) ENGINE = MyISAM AUTO_INCREMENT = 3 

로드 사용자

INSERT INTO users(id, username, gender) 
    VALUES(1, 'john', NULL) 
GO 
INSERT INTO users(id, username, gender) 
    VALUES(2, 'jane', NULL) 
GO 

이 식물에게

CREATE TABLE plants ( 
    id  int(11) AUTO_INCREMENT NOT NULL, 
    name varchar(200) NOT NULL, 
    PRIMARY KEY(id) 
) ENGINE = MyISAM AUTO_INCREMENT = 6 

로드 식물

INSERT INTO plants(id, name) 
    VALUES(1, 'fern1') 
GO 
INSERT INTO plants(id, name) 
    VALUES(2, 'fern2') 
GO 
INSERT INTO plants(id, name) 
    VALUES(3, 'orchid1') 
GO 
INSERT INTO plants(id, name) 
    VALUES(4, 'orchid2') 
GO 
INSERT INTO plants(id, name) 
    VALUES(5, 'lilly1') 
만들기

조인 테이블 만들기 너무 많은 웹 플랫폼이 2 열 기본 조인 테이블을 제대로 업데이트하지 않기 때문에 여기서 대리 키를 사용합니다. 또한, 이러한 유형의 조인에 메타 데이터/세부 정보를 추가하는 일이 자주 발생했으며,이 작업 없이는 지저분 해졌습니다. 참고 동일한 플랜트 유형을 추가하는 동일한 사용자의 조합을 제한하지는 않지만 쉽게 할 수 있습니다.

CREATE TABLE plants_users ( 
    id   int(11) AUTO_INCREMENT NOT NULL, 
    plant_id int(11) NOT NULL, 
    user_id  int(11) NOT NULL, 
    PRIMARY KEY(id) 
) 
ENGINE = MyISAM 
AUTO_INCREMENT = 8 
GO 
CREATE INDEX fk_plant_id USING BTREE 
    ON plants_users(plant_id) 
GO 
CREATE INDEX fk_user_id USING BTREE 
    ON plants_users(user_id) 

로드 표 가입

INSERT INTO plants_users(id, plant_id, user_id) 
    VALUES(1, 1, 1) 
GO 
INSERT INTO plants_users(id, plant_id, user_id) 
    VALUES(2, 2, 1) 
GO 
INSERT INTO plants_users(id, plant_id, user_id) 
    VALUES(3, 3, 1) 
GO 
INSERT INTO plants_users(id, plant_id, user_id) 
    VALUES(4, 4, 1) 
GO 
INSERT INTO plants_users(id, plant_id, user_id) 
    VALUES(5, 2, 2) 
GO 
INSERT INTO plants_users(id, plant_id, user_id) 
    VALUES(6, 3, 2) 
GO 
INSERT INTO plants_users(id, plant_id, user_id) 
    VALUES(7, 5, 2) 

최종 쿼리 :

select 
    users.username, 
    plants.name 
from 
    users,plants,plants_users 
where 
    users.id = plants_users.user_id and 
    plants.id = plants_users.plant_id 

결과 :

user name 
    john fern1 
    john fern2 
    john orchid1 
    john orchid2 
    jane fern2 
    jane orchid1 
    jane lilly1 
+0

. 한 가지 질문 : PHP $ _POST를 사용하는 메서드를 사용하는 경우 3 개의 테이블을 모두 업데이트하려면이 테이블을 모두 게시해야합니까? – pepe

+0

아니요 - plants_users 테이블에 레코드를 삽입하기 만하면됩니다. 요청 변수에 plant_id가 포함되어야하며 세션 변수는 user_id를 보유해야합니다. 새 사용자를 추가하거나 새로운 유형의 플랜트를 추가하려면 별도의 SQL 쿼리가 필요합니다. – johnrobertfitz

관련 문제