您提供的信息很少,所以我必須再次猜測我自己的場景 ,這是可能的。
我們爲零售商提供信息。每個零售商都有很多客戶,並且一個客戶可能成爲許多零售商的客戶,所以這種關係需要多對多的關係,這需要另一個表來提供幫助。
對於每一位零售商和零售商,我們都保持獨特的收費(預測)。 一次收費只屬於一位顧客。
Year1,year2字段否,年份必須是單個字段中沒有多少字段。和 ,因爲這是一個有多個出現的字段(類似於電話的情況下) 好的做法需要其他表來幫助我們。所以沒有像 動態字段這樣的東西,字段是靜態的像石頭一樣的基礎規則!另外,如果我們在談論真正龐大的數據(我不認爲是這種情況,我們可能會打破 與特定年份相關的部分的收費表,例如 需要更多工作)。
一個非常重要的事情..你可能有一個特定的方式在你的腦海裏你將如何 呈現水平,垂直這個數據,第1年,第2年等..但是你永遠不會 讓這個想法干擾你的關係圖,視覺顯示(可隨時改變) 和er設計必須保持分開。
至於美國有一個小竅門,以保持田間小,這意味着更快的工作 和省略狀態table.It需要一個簡單的PHP函數,給定的狀態 例如,加利福尼亞州,當它存儲TINYINT而不是varchar加州。或者你可以保留一個 狀態表,其tinyint id作爲外鍵傳遞給收費表。 選擇你喜歡的任何一個。
/實體是零售商和客戶的推廣。一般化 需要處理類似的領域,例如零售商和客戶 有電子郵件,地址等。另一方面,客戶和零售商是 我們需要它來處理不同領域的實體的規範 例如我們不在乎一個退休者是否已婚!/
以下僅爲示例。
drop table if exists `Entity_Phone`;
drop table if exists `Retailer_Customer`;
drop table if exists `Charge`;
drop table if exists `Retailer`;
drop table if exists `Customer`;
drop table if exists `Entity`;
CREATE TABLE `Entity` (
`entity_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
/*example code 0 is for retailer and code 1 is for customer*/
`entity_code` tinyint not null,
`entity_other_field` VARCHAR(30) NOT NULL,
PRIMARY KEY (`entity_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
/*You don't have to use utf8 if not needed*/
/*Phone number, instead of only phone you can store more info
like multiple emails etc, just change the table name to make sense,
the datatype and in the php function that associates codes add
as many codes needed*/
CREATE TABLE `Entity_Phone` (
`entity_id` INT UNSIGNED NOT NULL ,
`phone` BIGINT UNSIGNED NOT NULL ,
/*code 1 is for fix phone, 2 is for mobile phone and 3 for fax*/
`identification_code` TINYINT UNSIGNED DEFAULT '1' NOT NULL,
PRIMARY KEY (`entity_id`),
CONSTRAINT `fk1EntData` FOREIGN KEY (`entity_id`)
REFERENCES `Entity` (`entity_id`)
ON DELETE CASCADE
) ENGINE=InnoDB ROW_FORMAT=COMPACT;
CREATE TABLE `Retailer` (
`retailer_fname` VARCHAR(30) NOT NULL,
`retailer_lname` VARCHAR(30) NOT NULL,
/*pkey directly shared from entity table, just with a different name*/
`retailer_id` INT UNSIGNED NOT NULL ,
PRIMARY KEY (`retailer_id`),
CONSTRAINT `fk1RetEnt` FOREIGN KEY (`retailer_id`)
REFERENCES `Entity` (`entity_id`)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
CREATE TABLE `Customer` (
`customer_fname` VARCHAR(30) NOT NULL,
`children_number` tinyint not null,
`customer_id` INT UNSIGNED NOT NULL ,
PRIMARY KEY (`customer_id`),
CONSTRAINT `fk1CustData` FOREIGN KEY (`customer_id`)
REFERENCES `Entity` (`entity_id`)
ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
CREATE TABLE `Retailer_Customer` (
`customer_id` INT UNSIGNED NOT NULL ,
`retailer_id` INT UNSIGNED NOT NULL ,
PRIMARY KEY (`customer_id`,`retailer_id`),
CONSTRAINT `fk1RetCust` FOREIGN KEY (`customer_id`)
REFERENCES `Entity` (`entity_id`)
ON DELETE CASCADE,
CONSTRAINT `fk2RetCust` FOREIGN KEY (`retailer_id`)
REFERENCES `Entity` (`entity_id`)
ON DELETE CASCADE
) ENGINE=InnoDB ROW_FORMAT=COMPACT;
/*
if you want to keep the state table... for example you might need to store
information for states so you need this table to keep those fields
CREATE TABLE `State` (
`state_id` tinyINT UNSIGNED NOT NULL ,
`state_name` varchar(50) not null ,
PRIMARY KEY (`state_id`),
unique(`state_name`)
) ENGINE=InnoDB ROW_FORMAT=COMPACT;
*/
CREATE TABLE `Charge` (
`retailer_id` INT UNSIGNED NOT NULL ,
`customer_id` INT UNSIGNED NOT NULL ,
`state_code` TINYINT UNSIGNED NOT NULL ,
/*state could be stored here directly as
varchar however this way it asks less space,
is faster and allows no orthographical erros
on insertion */
/*`state_id` tinyint UNSIGNED NOT NULL , if you want the state table*/
`charge_date_time` DATETIME NOT NULL,
index(`customer_id`),
PRIMARY KEY (`retailer_id`,`customer_id`,`charge_date_time`),
CONSTRAINT `fk1Charge` FOREIGN KEY (`retailer_id`)
REFERENCES `Retailer` (`retailer_id`)
ON DELETE CASCADE,
CONSTRAINT `fk2Charge` FOREIGN KEY (`customer_id`)
REFERENCES `Customer` (`customer_id`)
ON DELETE CASCADE
/* if you want the state table
,CONSTRAINT `fk2pr` FOREIGN KEY (`state_id`)
REFERENCES `State` (`state_id`)
ON DELETE CASCADE
*/
) ENGINE=InnoDB ROW_FORMAT=COMPACT;
/*This is how you insert a Retailer*/
insert into `Entity` (`entity_code`, `entity_other_field`)
values ('0','test');
insert into `Retailer` (`retailer_fname`, `retailer_lname`,
`retailer_id`) values ('John', 'Smith',(SELECT LAST_INSERT_ID()));
insert into `Entity_Phone` (`entity_id`, `phone`,`identification_code`) values
((SELECT LAST_INSERT_ID()), 123222,3);
/****************************************************/
/*This is how you insert a Customer*/
insert into `Entity` (`entity_code`, `entity_other_field`)
values ('1','test');
insert into `Customer` (`customer_fname`, `children_number`,
`customer_id`) values ('Jimm', 3,(SELECT LAST_INSERT_ID()));
insert into `Entity_Phone` (`entity_id`, `phone`,`identification_code`) values
((SELECT LAST_INSERT_ID()), 43543,3);
/****************************************************/
/*This is how you insert a charge*/
insert into `Charge` (`retailer_id`, `customer_id`,`state_code`,
`charge_date_time`)
values ((select `retailer_id` from `Retailer` where `retailer_fname`='John'),
(select `customer_id` from `Customer` where `customer_fname`='Jimm'),34,(now()));
/*This is how you retrieve a charge*/
select * from `Charge` where year(`charge_date_time`) ='2011'
感謝stereofrog,甚至當桌子每週都會增長? – ivantxo