简体   繁体   中英

Normalizing Database to 3NF

I'm creating a database that as to have at least 5 tables in 3NF. From what I can gather the database is 3NF when I look at the specifications for a 3NF daabase, but I'm not 100% sure which is why I'm asking here, and if it's not I'm wondering how to make it 3NF, so I can move on and try test queries, triggers and procedures on the database.

I have been basing my work off this sample database, which I assume is in 3NF from my understanding.

Any help or advice at all is really appreciated as I've been having this problem for a few days now.

CREATE TABLE IF NOT EXISTS xbox (
  game_id char(4) NOT NULL default '',
  game_name varchar(32) default NULL,
  developer varchar(32) default NULL,
  PRIMARY KEY  (game_id)
);

INSERT INTO xbox (game_id, game_name, developer) VALUES
('1001', 'Sunset Overdive', 'Insomniac Games'),
('1002', 'Quantum Break', 'Remedy Entertainment'),
('1003', 'Gears of War 4', 'The Coalition'),
('1004', 'Halo 5', '343 Industries'),
('1005', 'Forza 6', 'Turn10 Studios');


CREATE TABLE IF NOT EXISTS playstation (
  game_id char(4) NOT NULL default '',
  game_name varchar(32) default NULL,
  developer varchar(32) default NULL,
  PRIMARY KEY  (game_id)
);

INSERT INTO playstation (game_id, game_name, developer) VALUES
('2001', 'Bloodborne', 'From Software'),
('2002', 'The Witness', 'Thekla'),
('2003', 'Destiny', 'Bungie'),
('2004', 'Black Ops 3', 'Treyarch'),
('2005', 'DriveClub', 'Evolution');


CREATE TABLE IF NOT EXISTS pc (
  game_id char(4) NOT NULL default '',
  game_name varchar(32) default NULL,
  developer varchar(32) default NULL,
  PRIMARY KEY  (game_id)
);

INSERT INTO pc (game_id, game_name, developer) VALUES
('3001', 'Fallout 4', 'Bethesda'),
('3002', 'Tomb Raider', 'Crystal Dynamics'),
('3003', 'Overwatch', 'Blizzard'),
('3004', 'Rocket League', 'Psyonix'),
('3005', 'DiRT Rally', 'Codemasters');


CREATE TABLE IF NOT EXISTS nintendo (
  game_id char(4) NOT NULL default '',
  game_name varchar(32) default NULL,
  developer varchar(32) default NULL,
  PRIMARY KEY  (game_id)
);

INSERT INTO nintendo (game_id, game_name, developer) VALUES
('4001', 'Mario Kart 8', 'Nintendo'),
('4002', 'Mario Maker', 'Nintendo'),
('4003', 'Mario Party 9', 'Nintendo'),
('4004', 'Bayonetta 2', 'Nintendo'),
('4005', 'Splatoon', 'Nintendo');


CREATE TABLE IF NOT EXISTS sales (
  customer_id char(10) NOT NULL default '',
  game_id char(4) NOT NULL default '',
  quantity int(11) default NULL,
  paid double default NULL,
  payment varchar(32) default NULL,
  PRIMARY KEY  (game_id)
);

INSERT INTO sales (customer_id, game_id, quantity, paid, payment) VALUES
('1234567890', '1002', 1, 79.99, 'Debit'),
('0987654321', '2003', 1, 50, 'Credit'),
('1122334455', '2001', 2, 120, 'Cash'),
('6677889900', '4004', 3, 110.49, 'Cash'),
('1357924680', '3002', 1, 50, 'Credit');


CREATE TABLE IF NOT EXISTS products (
  game_id char(10) default NULL,
  platform varchar(32) default NULL,
  stock int(11) default NULL,
  price double default NULL,
  PRIMARY KEY  (game_id)
);

INSERT INTO products (game_id, platform, stock, price) VALUES
('1001', 'xbox', 33, 69.99),
('1002', 'xbox', 42, 79.99),
('1003', 'xbox', 50, 89.99),
('1004', 'xbox', 80, 59.99),
('1005', 'xbox', 10, 49.99),
('2001', 'playstation', 12, 55.99),
('2002', 'playstation', 44, 34.99),
('2003', 'playstation', 89, 45.99),
('2004', 'playstation', 65, 39.99),
('2005', 'playstation', 73, 19.99),
('3001', 'pc', 50, 69.99),
('3002', 'pc', 41, 49.99),
('3003', 'pc', 77, 59.99),
('3004', 'pc', 24, 19.99),
('3005', 'pc', 19, 24.99),
('4001', 'nintendo', 10, 19.99),
('4002', 'nintendo', 17, 39.99),
('4003', 'nintendo', 33, 28.99),
('4004', 'nintendo', 53, 34.99),
('4005', 'nintendo', 97, 15.99);

Since your xbox, pc, nintendo and playstation tables are all identical you may want to consider combining them into one and adding some sort of "type" column (or, as Prix mentioned, maybe have a one-to-many between platform and type in case the game can run on more than one platform).

With the current design you will start running into problems with any queries that are not type specific. If I am following your sample correctly, you are going to have to use the value of the products.platform column in order to determine which platform table contains the details you are looking for. This leads to row-at-a-time processing which is very inefficient.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM