SQL - Properties Structure
What is the best way to setup this table structure.
I have 3 tables, one table we'll call fruit and the other two tables are properties of that fruit so fruit_detailed and fruit_basic.
fruit
id | isDetailed
fruit_detailed
id | price | color | source | weight | fruitid?
fruit_basic
id | value | fruitid?
So what I want to do is have a property in fruit called isDetailed and if true, fill the fruit_detailed table with properties like color, weight, source, etc (multiple column). If its false then store in fruit_basic table with properties written in a single row.
开发者_JAVA技巧Storage sounds quite basic but if I want to select a fruit and get its properties, how can I determine which table to join? I could use and IF statement on the isDetailed property and then join like that but then you have two different types of properties coming back
How would you create the tables or do the join to get the properties? Am I missing something?
Personally, I see no need to split the basic and detailed attributes out into separate tables. I think they can/should all be columns of the main fruit table.
I would probably model this like so:
CREATE TABLE Fruits (
fruit_id INT NOT NULL,
CONSTRAINT PK_Fruit PRIMARY KEY CLUSTERED (fruit_id)
)
CREATE TABLE Fruit_Details (
fruit_id INT NOT NULL,
price MONEY NOT NULL,
color VARCHAR(20) NOT NULL,
source VARCHAR(20) NOT NULL,
weight DECIMAL(10, 4) NOT NULL,
CONSTRAINT PK_Fruit_Detail PRIMARY KEY CLUSTERED (fruit_id),
CONSTRAINT FK_Fruit_Detail_Fruit FOREIGN KEY (fruit_id) REFERENCES Fruit (fruit_id)
)
I had to guess on appropriate data types for some of the columns. I'm also not sure exactly what the "value" column is in your Fruit_Basic
table, so I've left that out for now.
Don't bother putting a bunch of IDs out there simply for the sake of having an ID column on every table. The Fruits->Fruit_Details relationship is a one-to-zero-or-one relationship. In other words, you can have at most one Fruit_Details row for each Fruits row. In some cases you might have no row in Fruit_Details for a particular row in Fruits.
When you're querying you can simply OUTER JOIN
from the Fruits
table to the Fruit_Details
table. If you get back a NULL
value for Fruit_Details.fruit_id
then you know that the fruit doesn't have any details. You can always include the Fruit_Details
columns, they'll just be NULL
if the row doesn't exist. That way you can always have homogeneous resultsets. As you've discovered, otherwise you end up having to worry about different column lists coming back depending on the row in question, which will lead to tons of headaches.
If you want to include an "isDetailed" column then you can just use this:
CASE WHEN Fruit_Details.fruit_id IS NULL THEN 0 ELSE 1 END AS isDetailed
This approach also has an advantage over putting all of the columns in one table because it lowers the number of NULL
columns in your database and depending on your data can substantially decrease storage requirements and improve performance.
I'm not sure why you would need to store a basic or detailed list of the fruit in different tables. You should just have 1 table and then leave some of the fields null if the information doesn't exist.
Assuming that value from fruit_basic is the same as price from fruit_detailed, you'd have something like this.
fruit
id | detail_id (fk to fruit_detailed table)
fruit_details
detail_id | price | color | source | weight
精彩评论