2012-01-31 2 views
1

나는 아래 두 가지 이유로 SQL 테이블 구조에 만족하지 않습니다. 나는 모든 항목을 나열하고 있음을 좋아하지 않아SQL 테이블 구조 피드백

  1. 는 1020 바이트 VARCHAR 변수의 주문 (orders.itemOrderIds)에 포함되어 있습니다. ID 번호를 묶는 더 우아한 방법이있는 것처럼 느껴집니다.

  2. 항목 테이블의 itemDescription 변수에서 내 Java 코드의 항목 (기본적으로 필드)에 대한 정보 추출에 의존합니다.

누구나 이러한 상황을 처리하는 가장 좋은 방법에 대한 조언이 있습니까? 나는이 웹 사이트에서 자바 코드로 테이블을 생성하는 것이 좋다는 것을 읽었다. 예를 들어, Java 코드는 orderI (orderId) _items라는 테이블을 생성하여 orderId와 함께 주문에 포함 된 모든 항목을 보유하게됩니다. 이 문제를 해결하는 가장 좋은 방법입니까?

CREATE TABLE IF NOT EXISTS customers 
(
id INT AUTO_INCREMENT, 
name VARCHAR(255) NOT NULL, 
email VARCHAR(255) NOT NULL, 
company VARCHAR(255) NOT NULL, 
address1 VARCHAR(255) NOT NULL, 
address2 VARCHAR(255), 
city VARCHAR(255) NOT NULL, 
province_state VARCHAR(255) NOT NULL, 
country VARCHAR(255) NOT NULL, 
zip VARCHAR(255), 
telephone VARCHAR(255), 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

CREATE TABLE IF NOT EXISTS orders 
(
id INT AUTO_INCREMENT, 
customerId INT NOT NULL, 
orderNum VARCHAR(255) NOT NULL, 
itemOrderIds VARCHAR(1020) NOT NULL, 
regName VARCHAR(255) NOT NULL, 
regCompany VARCHAR(255) NOT NULL, 
regEmail VARCHAR(255) NOT NULL, 
orderTime DATETIME NOT NULL, 
FOREIGN KEY(customerId) REFERENCES customers(id), 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

CREATE TABLE IF NOT EXISTS items 
(
itemNum VARCHAR(255) UNIQUE, 
itemName VARCHAR(255), 
itemTypeId SMALLINT NOT NULL, 
--itemDescription must hold all information needed to generate license keys in format 
-- Field_Name1: Field_Value1, Field_Name2: Field_Value2, ..... 
-- Field names are platform, version, (choose one: port, voiceName) 
itemDescription VARCHAR(1020), 
FOREIGN KEY(itemTypeId) REFERENCES item_types(id) ON DELETE CASCADE, 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

CREATE TABLE IF NOT EXISTS item_types 
(
id SMALLINT AUTO_INCREMENT, 
itemType VARCHAR(255) UNIQUE NOT NULL, 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

CREATE TABLE IF NOT EXISTS item_orders 
(
id INT AUTO_INCREMENT, 
itemNum VARCHAR(255) NOT NULL, 
licenseKey VARCHAR(255) NOT NULL, 
FOREIGN KEY(itemNum) REFERENCES items(itemNum), 
PRIMARY KEY(id) 
) ENGINE = INNODB; 

편집 :

CREATE TABLE IF NOT EXISTS Order_Items 
(
orderId INT NOT NULL, 
itemOrderId INT NOT NULL, 
PRIMARY KEY(orderId, itemOrderId) 
) ENGINE = INNODB; 
+0

대부분의 속성에'VARCHAR (255)'를 사용하면 냄새가 난다. – onedaywhen

+0

그것에 대해 더 자세히 말씀해 주시겠습니까? 나는 초심자 소프트웨어 개발자 (단지 1 년 경험)이다 그래서 어떤 통보든지 다량 평가 될 것입니다. – thatidiotguy

+0

'orderNum'값이 255 자 정도 밖에되지 않는다고 가정합니다. 그들은 아마도 길이가 크게 다르지 않을 것입니다. 값이 실제로 길이가 항상 10 자이면'CHAR (10)'이 적절할 것입니다 : 이는 사용자에게 중요한 데이터 속성을 알려주고 '길이없는'문자를 체크합니다. 이는 mySQL에서 특히 중요합니다. 이는 CHECK 제약 조건에 대한 지원이 부족하기 때문입니다. 냄새와 관련하여'VARCHAR (255) '를 사용하면 데이터 모델이 해당 기업에 대한 특정 지식을 가진 사람에 의해 설계되지 않았 음을 알 수 있습니다. HTH. – onedaywhen

답변

3

예, 당신이 OrderItem 교차 테이블이 필요 오히려 VARCHAR 필드에 주문 ID의 모든 비정규보다 (나는 보통 첫번째 이름에 부모 개체를 넣어). 이와 같이 필드를 적절하게 색인 할 수있는 방법이 없기 때문에 업데이트가 매우 어려워집니다.

database normalization에서 읽을 수 있습니다.이 예제는 첫 번째 유형의 예제입니다.

+0

그래서 내가 이렇게 테이블을 가져야한다고 말하고 있습니다. – thatidiotguy

1

가장 좋은 방법은 모든 데이터 구조를 적어도 3NF로 정규화하는 것입니다. 또한 주문 테이블에 대한 참조를 보유하고 별도의 테이블에서 주문 항목의 더 나은 저장 목록 - 지금으로

Database Normalization

.

0

주문 세부 테이블 (결합 테이블 아님)이 필요합니다. 왜? 주문 정보는 특정 날짜에 한정되기 때문에. 그 당시의 정보를 저장해야합니다. 따라서 주문 세부 정보에는 일반적으로 품목 번호, 품목 이름, 가격 (가격을 포함하는 것이 중요하며 2 년 후 가격이 아니라 주문이 판매 된 시점의 가격이 필요합니다) 및 옵션의 세부 정보가 포함됩니다. 색상, 주문한 품목 수 등을 표시 할 수 있습니다. 주문 표에는 배송 된 주소와 시간이 지남에 따라 변경되는 고객의 이름에 대한 세부 정보가 포함됩니다.

나는 또한 고객 테이블을 분해합니다. 고객은 일반적으로 여러 개의 주소, 전화 번호 및 이메일을 가질 수 있으며 각 주소는 별개의 관련 테이블이어야합니다.

+0

프로그램은 재정 정보를 상세하게 설명하지 않습니다. 고객이 라이센스 키를 분실하면 나중에 조회 할 수 있도록 주문 된 내용 만 기록합니다. 라이센스 키는 배송지 주소가 아닌 현재 주문한 정보에 따라 다릅니다. 제 프로그램 중 또 다른 프로그램은 재정 문제를 담당하고 있습니다. – thatidiotguy