开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜