Search code examples
sqlsql-serverdatabase-designcommerce

Designing a rudimentary Shopping Cart database


create table [User]
(
    UserId int primary key identity(1,1),
    FirstName nvarchar(256) not null,
    LastName nvarchar(256) not null,
)

create table Product
(
    ProductId int primary key identity(1,1),
    UnitPrice decimal(18,2) not null, //For catalog purposes.
    Name nvarchar(1000) not null,
    Description nvarchar(max) not null,
    Stock int not null
)

create table [Order]
(
    OrderId int primary key identity(1,1),
    UserId int foreign key references [User](UserId),
    ProductId int foreign key references Product(ProductId),
    UnitCost decimal(18,2) not null, //How much it actually cost when the person bought it.
    ItemCount int not null,
    Subtotal decimal(18,2) not null
)

create table OrderDetail
(
    OrderDetailId int primary key identity(1,1),
    ?

I'm stuck on the database design of the order system.

A user can choose n products to add to a order request. Any suggestions?


Following some advice given here, how would this feel? Any pitfalls?

create table [User]
(
    UserId int primary key identity(1,1),
    FirstName nvarchar(256) not null,
    LastName nvarchar(256) not null,
)

create table Product
(
    ProductId int primary key identity(1,1),
    UnitPrice decimal(18,2) not null,
    Name nvarchar(1000) not null,
    Description nvarchar(max) not null,
    Stock int not null
)

create table [Order]
(
    OrderId int primary key identity(1,1),
    UserId int foreign key references [User](UserId),
    DateOfOrder datetime not null
)

create table OrderDetail
(
    OrderDetailId int primary key identity(1,1),
    OrderId int foreign key references [Order](OrderId),    
    ProductId int foreign key references Product(ProductId),
    UnitCost decimal(18,2) not null,
    ItemCount int not null,
    Subtotal decimal(18,2) not null
)

Solution

  • Typically, you'd have the Order table with the top-level order information (who, when etc) and then an OrderItem (or OrderDetail) table which has a row for each product that forms part of the order including columns like:

    OrderId
    ProductId
    Quantity
    etc
    

    Good candidate for a PK on this OrderItem/OrderDetail table would be on OrderId + ProductId.

    So where you have columns like ProductId, UnitCost, ItemCount etc in the Order table, those are in the wrong place and should be in the OrderItem/OrderDetail table.

    Update: To set up a compound PK, you can do:

    create table OrderDetail
    (
        OrderId int foreign key references [Order](OrderId),    
        ProductId int foreign key references Product(ProductId),
        ...other columns...,
        CONSTRAINT PK_OrderDetail PRIMARY KEY(OrderId, ProductId)
    )