0

i'm new to MySql(3hours under my belt),just finished reading PHP & MYSQL for dummies 4th Edition and i'm currently to create a database that contains information about shops for practice.

The database i'm trying to create contains information about a list of stores.Each store will contain some basic information about the store,the industry(E.g Clothes, Food) the store is operating in, as well as their inventory.

While i currently have a table containing the store's name,description(which can be a short write up and/or a URL to the store's website), and a store ID(Which serves as the primary key)

create table Merchant(

MerchantID      SERIAL,
Industry        ENUM("Retail","Dining","Entertainment"),
Name            VARCHAR(1000) NOT NULL,
Description     VARCHAR(1000),
PRIMARY KEY(MerchantID)
)

Each store will then have multiple categories for what they are selling, and each categories will have multiple items.Would i be right in saying that what i am looking at is a One(Store) to Many(Categories) table linked to a One(Category) to Many(Items) table? The reason being that although the first table(Store to Categories) has a One to Many R/S, the second table(Category to Item) also has a One to Many, and NOT a Many to Many R/S as i am only looking at a singular category which contains multiple items in it.

Table for Categories:

Create table Categories(

CategoryID      SERIAL references MerchantID,
Category        VARCHAR(50) NOT NULL,
PRIMARY KEY(CategoryID)

)

Table for Items:

Create table Items(

ItemID      Serial references CategoryID,
Item        VARCHAR(50) NOT NULL,
PRIMARY KEY(ItemID)

)

Is the code above correct? Or do i have to enter all the Primary Keys that are one level above. E.g:

Create table Item(

MerchantID      SERIAL,
CategoryID      SERIAL,
ItemID          SERIAL,
Item            VARCHAR(50),
PRIMARY KEY(MerchantID,CategoryID,ItemID)
)

Furthermore, is there any difference between having VARCHAR(50) and VARCHAR(1000) seeing as MYSQL would automatically get rid of all the unused space?Also, is there any way to further optimise the database for performance etc.?

4

3 回答 3

0

There are some problems with your plan. The first one is using an enum in your merchant table. Adding a new industry later on would be a lot easier with a separate table for industries.

Your syntax for categories might not run. I don't use MySQL but what you have is not valid for other RDBMSs. When you use the "references" keyword, it should be while declaring a foreign key. So this:

Create table Categories(
CategoryID      SERIAL references MerchantID,
Category        VARCHAR(50) NOT NULL,
PRIMARY KEY(CategoryID)
)

should probably resemble this:

Create table Categories(
CategoryID      SERIAL not null,
MerchantID integer not null,
Category        VARCHAR(50) NOT NULL,
PRIMARY KEY(CategoryID),
foreign key merchantID references (merchant.merchantID)
)

None of your table have foreign keys. If the book you used didn't address those, I've heard good things about "Database Design for Mere Mortals".

These observations should get you started.

于 2013-05-19T13:10:54.507 回答
0

my first reactions/impressions:

  1. have a Merchant table, id, name
  2. consider whether you want the ENUM for industry, or make that a proper table
  3. have an Item table - do not link this like you are trying - this one should be only about the items
  4. Link Item to Merchant in a separate table - item_id, merchant_id - maybe include other things like price here.
  5. have a Category table, id, name, description
  6. link the Item to a Category.
于 2013-05-19T13:27:50.803 回答
0

When you create relationship between tables (One-to-Many) you should have Primary Key (PK) to Foreign Key (FK), the PK has the One side and the FK has the many side. In your case you got wrong concept of using the FK as well as the Serial data type. For example you have the Merchant Table (your One-side) structure like this:

create table Merchant(
 MerchantID      SERIAL,
 Industry        ENUM("Retail","Dining","Entertainment"),
 Name            VARCHAR(1000) NOT NULL,
 Description     VARCHAR(1000),
 PRIMARY KEY(MerchantID)
 )

And then your related table Categories (the Many-side)

Create table Categories(
CategoryID      SERIAL references MerchantID,
Category        VARCHAR(50) NOT NULL,
PRIMARY KEY(CategoryID)

First let's tackle the Serial data type. A Serial data type in mySQL is actually a BIGINT NOT NULL AUTO_INCREMENT data type which is good for PK. So, in Category table the MerchantID is auto_increment which is ok. Now, in your Category table your Primary key is CategoryID is also Serial which is auto_increment but it references MerchantID. So, for example if Store 'A' has two Categories then your first value for your PK in Merchant Table is 1. Now in your Category table since it is also auto_increment that means you have values 1 and 2. In which 1 value would match the 1 value of Merchant but the 2 value would not match because there is none (except you add another store). In other words the values of the PK (MerchantID) in Merchant table does not coincide with the values of FK CategoryID in Categories table.

In other words you don't use Serial but simply BIGINT in your related field, namely, the MerchantID. So, it should be like this now.

 create table Merchant(
 MerchantID      SERIAL,
 Industry        ENUM("Retail","Dining","Entertainment"),
 Name            VARCHAR(1000) NOT NULL,
 Description     VARCHAR(1000),
 PRIMARY KEY(MerchantID)
 )

Create table Categories(
MerchantID      BIGINT,
Category        VARCHAR(50) NOT NULL,
PRIMARY KEY(MerchantID, Category)
)

Now, since you want to create the relationship between Category (One-side) to Items (Many-side) then you have to retain the CategoryID in your table which now changes the Categories table to:

 Create table Categories(
 CategoryID      SERIAL,
 MerchantID      BIGINT,
 Category        VARCHAR(50) NOT NULL,
 PRIMARY KEY(CategoryID),
 FOREIGN KEY(MerchantID) references Merchant(MerchantID)
 )

Now in your Items table with One-to-Many, that is, a Category could have many Items then you Items table will change into this:

Create table Items(
ItemID      Serial,
CategoryID  BIGINT,
Item        VARCHAR(50) NOT NULL,
PRIMARY KEY(ItemID),
FOREIGN KEY(CategoryID) references Categories(CategoryID)
)

This is now basically my 2nd point. In this case the Items being the many-side has the FK CategoryID from Categories PK which is also CategoryID.

And I would agree with Dan Brauck that you don't use Enum as your data type because it is difficult to extend or not flexible. So, your Merchant table should have this structure now.

create table Merchant(
 MerchantID      SERIAL,
 Industry        VARCHAR(50) NOT NULL,
 Name            VARCHAR(1000) NOT NULL,
 Description     VARCHAR(1000),
 PRIMARY KEY(MerchantID)
 )

I hope by the way that you also understand Normalization concept which is very important in Database Design. Like the links below:

http://www.tutorialspoint.com/sql/first-normal-form.htm
https://en.wikipedia.org/wiki/Database_normalization
于 2013-05-19T14:19:38.040 回答