Guide To Design Database For Restaurant Order System In MySQL

By bhagwatchouhan
Guide To Design Database For Restaurant Order System In MySQL

This tutorial provides complete steps to design a database schema of the restaurant ordering system to manage the users, table bookings, menus, inventory, orders, and payments. It provides the food order database design to manage the food orders for restaurants. It can be further used to develop on-premises restaurant order system applications.

Such ordering systems are implemented to automate order processing and efficiently deal with peak ordering times, thus improving customer satisfaction with less efforts – a win-win situation for restaurant businesses.

The Entity Relationship Diagram or visual database design is shown below.

Restaurant Ordering System Database Schema

Restaurant Ordering System

Notes: It can be used for online booking of the tables and pre-order before reaching the restaurant. The security can also be handled by following RBAC Database in MySQL.

You can also visit the popular tutorials including How To Install MySQL 8 on Ubuntu, How To Install MySQL 8 on Windows, How To Install MySQL 8 With Workbench On Windows 10, RBAC Database in MySql, Blog Database in MySql, Quiz Database In MySQL, Poll & Survey Database In MySQL, Online Shopping Cart Database, and Learn Basic SQL Queries In MySQL.

 

Restaurant Database

The very first step is to create the Restaurant Database. It can be created using the query as shown below.

CREATE SCHEMA `restaurant` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

I have used the character set utf8mb4 to support a wide range of characters.

 

User Table

In this section, we will design the User Table to store user information. The same table can be used to manage different types of users including admins, chefs, agents, and customers. It can be used to relate the users with Menus, Items, Table Bookings, and Orders. Users can track their own tables and orders. Below mentioned is the description of all the columns of the User Table.

IdThe unique id to identify the user.
First NameThe first name of the user.
Middle NameThe middle name of the user.
Last NameThe last name of the user.
MobileThe mobile number of the user. It can be used for login and registration purposes.
EmailThe email of the user. It can be used for login and registration purposes.
Password HashThe password hash generated by the appropriate algorithm. We must avoid storing plain or encrypted passwords.
AdminThe flag to identify whether the user is an administrator. It's not required if RBAC tables are created by following the RBAC database design.
VendorThe flag to identify whether the user can receive inventory orders. It's not required if RBAC tables are created by following the RBAC database design.
ChefThe flag to identify whether the user can cook the items. It's not required if RBAC tables are created by following the RBAC database design.
AgentThe flag to identify whether the user can host a table. It's not required if RBAC tables are created by following the RBAC database design.
Registered AtThis column can be used to calculate the life of the user with the application.
Last LoginIt can be used to identify the last login of the user.
IntroThe brief introduction of the Vendor User to be displayed on the Product Page.
ProfileThe vendor details to be displayed on the Product Page.

The User Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`user` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `firstName` VARCHAR(50) NULL DEFAULT NULL,
  `middleName` VARCHAR(50) NULL DEFAULT NULL,
  `lastName` VARCHAR(50) NULL DEFAULT NULL,
  `mobile` VARCHAR(15) NULL,
  `email` VARCHAR(50) NULL,
  `passwordHash` VARCHAR(32) NOT NULL,
  `admin` TINYINT(1) NOT NULL DEFAULT 0,
  `vendor` TINYINT(1) NOT NULL DEFAULT 0,
  `chef` TINYINT(1) NOT NULL DEFAULT 0,
  `agent` TINYINT(1) NOT NULL DEFAULT 0,
  `registeredAt` DATETIME NOT NULL,
  `lastLogin` DATETIME NULL DEFAULT NULL,
  `intro` TINYTEXT NULL DEFAULT NULL,
  `profile` TEXT NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `uq_mobile` (`mobile` ASC),
  UNIQUE INDEX `uq_email` (`email` ASC) );

 

Ingredient, Item, Recipe, and Menu Tables

In this section, we will design the Ingredient, Item, Recipe, and Menu Tables to store the menus and items data.

Below mentioned is the description of all the columns of the Ingredient Table. The Ingredient Table is also mapped to identify the supplier who can supply the ingredient to re-fill the inventory. In a more advanced scenario, there can be a separate table to store the ingredient and supplier relationship to support multiple suppliers for the same ingredient.

IdThe unique id to identify the ingredient.
User IdThe user id to identify the admin.
Vendor IdThe vendor id to identify the supplier.
TitleThe ingredient title to be displayed on the Item Recipe.
SlugThe unique slug to be used as GID of the Ingredient.
SummaryThe summary to mention the key highlights.
TypeThe type to distinguish between the different ingredient types.
SKUThe Stock Keeping Unit to track the ingredient inventory.
QuantityThe available quantity of the ingredient.
UnitThe Units of Measure assigned to the ingredient.
Created AtIt stores the date and time at which the ingredient is created.
Updated AtIt stores the date and time at which the ingredient is updated.
ContentThe column used to store the additional details of the ingredient.

It uses the columns quantity and unit to track the stock available in the ingredient inventory. The Ingredient Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`ingredient` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `userId` BIGINT NOT NULL,
  `vendorId` BIGINT DEFAULT NULL,
  `title` VARCHAR(75) NOT NULL,
  `slug` VARCHAR(100) NOT NULL,
  `summary` TINYTEXT NULL,
  `type` SMALLINT(6) NOT NULL DEFAULT 0,
  `sku` VARCHAR(100) NOT NULL,
  `quantity` FLOAT NOT NULL DEFAULT 0,
  `unit` SMALLINT(6) NOT NULL DEFAULT 0,
  `createdAt` DATETIME NOT NULL,
  `updatedAt` DATETIME NULL DEFAULT NULL,
  `content` TEXT NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `uq_slug` (`slug` ASC),
  INDEX `idx_ingredient_user` (`userId` ASC),
  CONSTRAINT `fk_ingredient_user`
    FOREIGN KEY (`userId`)
    REFERENCES `restaurant`.`user` (`id`)
    ON DELETE RESTRICT
    ON UPDATE NO ACTION);
ALTER TABLE `restaurant`.`ingredient` ADD INDEX `idx_ingredient_vendor` (`vendorId` ASC);
ALTER TABLE `restaurant`.`ingredient` ADD CONSTRAINT `fk_ingredient_vendor` FOREIGN KEY (`vendorId`) REFERENCES `restaurant`.`user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION;

Below mentioned is the description of all the columns of the Item Table. The Item Table is also mapped to identify the supplier who can supply the non-cooking item to re-fill the inventory. In a more advanced scenario, there can be a separate table to store the item and supplier relationship to support multiple suppliers for the same item.

Notes: We can also use the same table to store the ingredients and items to simplify the restaurant and supplier orders. In such a case, a self-join is required to identify the item ingredients. Also, the columns cooking and price are not useful for ingredient rows.

IdThe unique id to identify the item.
User IdThe user id to identify the admin.
Vendor IdThe vendor id to identify the supplier.
TitleThe item title to be displayed on the Menu.
SlugThe unique slug to be used as GID of the item.
SummaryThe summary to mention the key highlights.
TypeThe type to distinguish between the different item types.
CookingThe flag to identify whether cooking is required for the item.
SKUThe Stock Keeping Unit to track the item inventory. It's required only if the item is not associated with ingredients.
PriceThe selling price of either one unit or a single serving.
QuantityThe available quantity of the item. It's required only if the item is not associated with ingredients.
UnitThe Units of Measure assigned to the item. It's required only if the item is not associated with ingredients.
RecipeThe instructions required to cook the item.
InstructionsThe instructions required to serve the item.
Created AtIt stores the date and time at which the item is created.
Updated AtIt stores the date and time at which the item is updated.
ContentThe column used to store the additional details of the item.

Similar to Ingredient Table, it uses the columns quantity and unit to track the stock available in the item inventory. The Item Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`item` (
  `id` BIGINT NOT NULL AUTO_INCREMENT,
  `userId` BIGINT NOT NULL,
  `vendorId` BIGINT DEFAULT NULL,
  `title` VARCHAR(75) NOT NULL,
  `slug` VARCHAR(100) NOT NULL,
  `summary` TINYTEXT NULL,
  `type` SMALLINT(6) NOT NULL DEFAULT 0,
  `cooking` TINYINT(1) NOT NULL DEFAULT 0,
  `sku` VARCHAR(100) NOT NULL,
  `price` FLOAT NOT NULL DEFAULT 0,
  `quantity` FLOAT NOT NULL DEFAULT 0,
  `unit` SMALLINT(6) NOT NULL DEFAULT 0,
  `recipe` TEXT NULL DEFAULT NULL,
  `instructions` TEXT NULL DEFAULT NULL,
  `createdAt` DATETIME NOT NULL,
  `updatedAt` DATETIME NULL DEFAULT NULL,
  `content` TEXT NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `uq_slug` (`slug` ASC),
  INDEX `idx_item_user` (`userId` ASC),
  CONSTRAINT `fk_item_user`
    FOREIGN KEY (`userId`)
    REFERENCES `restaurant`.`user` (`id`)
    ON DELETE RESTRICT
    ON UPDATE NO ACTION);
ALTER TABLE `restaurant`.`item`
ADD INDEX `idx_item_vendor` (`vendorId` ASC);
ALTER TABLE `restaurant`.`item`
ADD CONSTRAINT `fk_item_vendor`
FOREIGN KEY (`vendorId`)
REFERENCES `restaurant`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

The Recipe Table can be used to track the quantity of the ingredients required for an item for a single serving. Below mentioned is the description of all the columns of the Recipe Table.

IdThe unique id to identify the recipe.
Item IdThe item id to identify the item.
Ingredient IdThe ingredient id to identify the ingredient.
QuantityThe quantity of the ingredient required to cook the item for a single serving.
UnitThe Units of Measure to identify the ingredient quantity required for the item.
InstructionsThe ingredient instructions required to cook the item.

The Recipe Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`recipe` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`itemId` BIGINT NOT NULL,
`ingredientId` BIGINT NOT NULL,
`quantity` FLOAT NOT NULL DEFAULT 0,
`unit` SMALLINT(6) NOT NULL DEFAULT 0,
`instructions` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_recipe_item` (`itemId` ASC),
UNIQUE INDEX `uq_recipe_item_ingredient` (`itemId` ASC, `ingredientId` ASC),
CONSTRAINT `fk_recipe_item`
FOREIGN KEY (`itemId`)
REFERENCES `restaurant`.`item` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION)
ENGINE = InnoDB;

ALTER TABLE `restaurant`.`recipe`
ADD INDEX `idx_recipe_ingredient` (`ingredientId` ASC);
ALTER TABLE `restaurant`.`recipe`
ADD CONSTRAINT `fk_recipe_ingredient`
FOREIGN KEY (`ingredientId`)
REFERENCES `restaurant`.`ingredient` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION;

Below mentioned is the description of all the columns of the Menu Table. The Menu Table can be used to store the multiple menus of the same restaurant.

IdThe unique id to identify the menu.
User IdThe user id to identify the admin.
TitleThe menu title to be displayed on the Menu Card.
SlugThe unique slug to be used as GID of the menu.
SummaryThe summary to mention the key highlights of the menu card.
TypeThe type to distinguish between the different menu types.
Created AtIt stores the date and time at which the item is created.
Updated AtIt stores the date and time at which the item is updated.
ContentThe column used to store the additional details of the menu.

The Menu Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`menu` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`userId` BIGINT NOT NULL,
`title` VARCHAR(75) NOT NULL,
`slug` VARCHAR(100) NOT NULL,
`summary` TINYTEXT NULL,
`type` SMALLINT(6) NOT NULL DEFAULT 0,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NULL DEFAULT NULL,
`content` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `uq_slug` (`slug` ASC),
INDEX `idx_menu_user` (`userId` ASC),
CONSTRAINT `fk_menu_user`
FOREIGN KEY (`userId`)
REFERENCES `restaurant`.`user` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION);

The Menu Item Table can be used to track the items available in the Menu Card. Below mentioned is the description of all the columns of the Menu Item Table.

IdThe unique id to identify the menu item.
Menu IdThe menu id to identify the menu.
Item IdThe item id to identify the item.
ActiveThe flag to check whether the item is available.

The Menu Item Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`menu_item` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`menuId` BIGINT NOT NULL,
`itemId` BIGINT NOT NULL,
`active` TINYINT(1) NOT NULL DEFAULT 1,
PRIMARY KEY (`id`),
INDEX `idx_menu_item_menu` (`menuId` ASC),
UNIQUE INDEX `uq_menu_item` (`menuId` ASC, `itemId` ASC),
CONSTRAINT `fk_menu_item_menu`
FOREIGN KEY (`menuId`)
REFERENCES `restaurant`.`menu` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION)
ENGINE = InnoDB;

ALTER TABLE `restaurant`.`menu_item`
ADD INDEX `idx_menu_item_item` (`itemId` ASC);
ALTER TABLE `restaurant`.`menu_item`
ADD CONSTRAINT `fk_menu_item_item`
FOREIGN KEY (`itemId`)
REFERENCES `restaurant`.`item` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION;

The Item Chef Table can be used to identify the Chef assigned to cook the item. Below mentioned is the description of all the columns of the Item Chef Table.

IdThe unique id to identify the menu item.
Item IdThe item id to identify the item.
Chef IdThe chef id to identify the user.
ActiveThe flag to check whether the chef is available to cook the item.

The Item Chef Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`item_chef` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`itemId` BIGINT NOT NULL,
`chefId` BIGINT NOT NULL,
`active` TINYINT(1) NOT NULL DEFAULT 1,
PRIMARY KEY (`id`),
INDEX `idx_item_chef_item` (`itemId` ASC),
UNIQUE INDEX `uq_item_chef` (`itemId` ASC, `chefId` ASC),
CONSTRAINT `fk_item_chef_item`
FOREIGN KEY (`itemId`)
REFERENCES `restaurant`.`item` (`id`)
ON DELETE CASCADE
ON UPDATE NO ACTION)
ENGINE = InnoDB;

ALTER TABLE `restaurant`.`item_chef`
ADD INDEX `idx_item_chef_chef` (`chefId` ASC);
ALTER TABLE `restaurant`.`item_chef`
ADD CONSTRAINT `fk_item_chef_chef`
FOREIGN KEY (`chefId`)
REFERENCES `restaurant`.`user` (`id`)
ON DELETE CASCADE
ON UPDATE NO ACTION;

TableTop and Booking Tables

In this section, we will design the TableTop and Booking Tables to store the restaurant tables and their booking details.

The TableTop Table can be used to store the details of the tables at the restaurant. The status of the table can be Free, Reserved, and Active. I have used TableTop instead of Table to distinguish it from the table keyword of MySQL. Below mentioned is the description of all the columns of the TableTop Table.

IdThe unique id to identify the table.
CodeThe table code.
StatusThe review rating.
CapacityThe total seating capacity of the Table.
Created AtIt stores the date and time at which the table is created.
Updated AtIt stores the date and time at which the table is updated.
ContentThe column used to store the additional details of the table.

The TableTop Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`table_top` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`code` VARCHAR(100) NOT NULL,
`status` SMALLINT(6) NOT NULL DEFAULT 0,
`capacity` SMALLINT(6) NOT NULL DEFAULT 0,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NULL DEFAULT NULL,
`content` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`));

Booking Table can be used to book the restaurant tables either online or on-premises. A logged-in or existing user can also be associated with Booking. It also assumes that only the tables having status Free can be Reserved. The table status can be changed to Reserved after the booking is confirmed. Also, the table status can be set to Active as soon as the guests occupy it. Below mentioned is the description of all the columns of the Booking Table.

Notes: The Booking Table does not cover the payments involved in booking the table. It can be further updated by adding additional columns to handle the payments involved in booking the table.

IdThe unique id to identify the booking.
Table IdThe table id to identify the table associated with the booking.
User IdThe user id to identify the registered user associated with the booking.
TokenThe unique token associated with the booking.
StatusThe status of the booking can be New, Lounge, Active, and Complete.
First NameThe first name of the guest.
Middle NameThe middle name of the guest.
Last NameThe last name of the user.
MobileThe mobile number of the user.
EmailThe email of the user.
Line 1The first line to store address.
Line 2The second line to store address.
CityThe city of the address.
ProvinceThe province of the address.
CountryThe country of the address.
Created AtIt stores the date and time at which the booking is created.
Updated AtIt stores the date and time at which the booking is updated.
ContentThe column used to store the additional details of the booking.

The Booking Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`booking` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`tableId` BIGINT NOT NULL,
`userId` BIGINT NULL DEFAULT NULL,
`token` VARCHAR(100) NOT NULL,
`status` SMALLINT(6) NOT NULL DEFAULT 0,
`firstName` VARCHAR(50) NULL DEFAULT NULL,
`middleName` VARCHAR(50) NULL DEFAULT NULL,
`lastName` VARCHAR(50) NULL DEFAULT NULL,
`mobile` VARCHAR(15) NULL,
`email` VARCHAR(50) NULL,
`line1` VARCHAR(50) NULL DEFAULT NULL,
`line2` VARCHAR(50) NULL DEFAULT NULL,
`city` VARCHAR(50) NULL DEFAULT NULL,
`province` VARCHAR(50) NULL DEFAULT NULL,
`country` VARCHAR(50) NULL DEFAULT NULL,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NULL DEFAULT NULL,
`content` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_booking_table` (`tableId` ASC),
CONSTRAINT `fk_booking_table`
FOREIGN KEY (`tableId`)
REFERENCES `restaurant`.`table_top` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);

ALTER TABLE `restaurant`.`booking`
ADD INDEX `idx_booking_user` (`userId` ASC);
ALTER TABLE `restaurant`.`booking`
ADD CONSTRAINT `fk_booking_user`
FOREIGN KEY (`userId`)
REFERENCES `restaurant`.`user` (`id`)
ON DELETE CASCADE
ON UPDATE NO ACTION;

The Booking Item Table is required to track the items ordered by the guest. Below mentioned is the description of all the columns of the Booking Item Table.

IdThe unique id to identify the booking item.
Booking IdThe booking id to identify the booking associated with the booking item.
Item IdThe item id to identify the item associated with the booking item.
SKUThe SKU of the item while ordering it.
PriceThe selling price of the item while ordering it.
DiscountThe discount of the item while ordering it.
QuantityThe quantity of the item ordered by the user. It can be either the multiplier of the item unit or single serving.
UnitThe Units of Measure while ordering the Item.
StatusThe status to track the item progress. It can be New, Kitchen, Cooking, Cooked, Served.
Created AtIt stores the date and time at which the booking item is created.
Updated AtIt stores the date and time at which the booking item is updated.
ContentThe column used to store the additional details of the booking item.

The Booking Item Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`booking_item` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`bookingId` BIGINT NOT NULL,
`itemId` BIGINT NOT NULL,
`sku` VARCHAR(100) NOT NULL,
`price` FLOAT NOT NULL DEFAULT 0,
`discount` FLOAT NOT NULL DEFAULT 0,
`quantity` FLOAT NOT NULL DEFAULT 0,
`unit` SMALLINT(6) NOT NULL DEFAULT 0,
`status` SMALLINT(6) NOT NULL DEFAULT 0,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NULL DEFAULT NULL,
`content` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_booking_item_booking` (`bookingId` ASC),
CONSTRAINT `fk_booking_item_booking`
FOREIGN KEY (`bookingId`)
REFERENCES `restaurant`.`booking` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION);

ALTER TABLE `restaurant`.`booking_item`
ADD INDEX `idx_booking_item_item` (`itemId` ASC);
ALTER TABLE `restaurant`.`booking_item`
ADD CONSTRAINT `fk_booking_item_item`
FOREIGN KEY (`itemId`)
REFERENCES `restaurant`.`item` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION;

Order Table and Order Item Table

This section provides the tables to manage the orders. A logged-in user can also be associated with the order. The order table can be used to store the completed bookings and vendor orders. The vendor orders status can be set to new while placing the order and it can be set to complete after receiving the items from the vendor. Also, the item price has to be filled manually after receiving the items from the vendor. Below mentioned is the description of all the columns of the Order Table.

IdThe unique id to identify the order.
User IdThe user id to identify the guest associated with the order.
Vendor IdThe vendor id to identify the vendor associated with the order.
TokenThe unique token associated with the order to relate it with the booking. The same token can also be passed to the Payment Gateway if required.
StatusThe status of the order can be New, Checkout, Paid, Failed, Shipped, Delivered, Returned, and Complete. The status Shipped, Delivered, and Returned can be used for the vendor orders.
Sub TotalThe total price of the Order Items.
Item DiscountThe total discount of the Order Items.
TaxThe tax on the Order Items.
ShippingThe shipping charges of the Order Items.
TotalThe total price of the Order including tax and shipping. It excludes the items discount.
PromoThe promo code of the Order.
DiscountThe total discount of the Order based on the promo code or store discount.
Grand TotalThe grand total of the order to be paid by the guest to the restaurant or the restaurant to the vendor.
First NameThe first name of the user.
Middle NameThe middle name of the user.
Last NameThe last name of the user.
MobileThe mobile number of the user.
EmailThe email of the user.
Line 1The first line to store address.
Line 2The second line to store address.
CityThe city of the address.
ProvinceThe province of the address.
CountryThe country of the address.
Created AtIt stores the date and time at which the order is created.
Updated AtIt stores the date and time at which the order is updated.
ContentThe column used to store the additional details of the order.

The Order Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`order` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`userId` BIGINT NULL DEFAULT NULL,
`vendorId` BIGINT NULL DEFAULT NULL,
`token` VARCHAR(100) NOT NULL,
`status` SMALLINT(6) NOT NULL DEFAULT 0,
`subTotal` FLOAT NOT NULL DEFAULT 0,
`itemDiscount` FLOAT NOT NULL DEFAULT 0,
`tax` FLOAT NOT NULL DEFAULT 0,
`shipping` FLOAT NOT NULL DEFAULT 0,
`total` FLOAT NOT NULL DEFAULT 0,
`promo` VARCHAR(50) NULL DEFAULT NULL,
`discount` FLOAT NOT NULL DEFAULT 0,
`grandTotal` FLOAT NOT NULL DEFAULT 0,
`firstName` VARCHAR(50) NULL DEFAULT NULL,
`middleName` VARCHAR(50) NULL DEFAULT NULL,
`lastName` VARCHAR(50) NULL DEFAULT NULL,
`mobile` VARCHAR(15) NULL,
`email` VARCHAR(50) NULL,
`line1` VARCHAR(50) NULL DEFAULT NULL,
`line2` VARCHAR(50) NULL DEFAULT NULL,
`city` VARCHAR(50) NULL DEFAULT NULL,
`province` VARCHAR(50) NULL DEFAULT NULL,
`country` VARCHAR(50) NULL DEFAULT NULL,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NULL DEFAULT NULL,
`content` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_order_user` (`userId` ASC),
CONSTRAINT `fk_order_user`
FOREIGN KEY (`userId`)
REFERENCES `restaurant`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);

ALTER TABLE `restaurant`.`order`
ADD INDEX `idx_order_vendor` (`vendorId` ASC);
ALTER TABLE `restaurant`.`order`
ADD CONSTRAINT `fk_order_vendor`
FOREIGN KEY (`vendorId`)
REFERENCES `restaurant`.`user` (`id`)
ON DELETE RESTRICT
ON UPDATE NO ACTION;

Below mentioned is the description of all the columns of the Order Item Table.

IdThe unique id to identify the ordered item.
Item IdThe product id to identify the item associated with the ordered item.
Order IdThe order id to identify the order associated with the ordered item.
SKUThe SKU of the item while ordering it.
PriceThe price of the item while ordering it.
DiscountThe discount of the item while ordering it.
QuantityThe quantity of the item selected by the user.
UnitThe Units of Measure while ordering the Item.
Created AtIt stores the date and time at which the ordered item is created.
Updated AtIt stores the date and time at which the ordered item is updated.
ContentThe column used to store the additional details of the ordered item.

The Order Item Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`order_item` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`orderId` BIGINT NOT NULL,
`itemId` BIGINT NOT NULL,
`sku` VARCHAR(100) NOT NULL,
`price` FLOAT NOT NULL DEFAULT 0,
`discount` FLOAT NOT NULL DEFAULT 0,
`quantity` FLOAT NOT NULL DEFAULT 0,
`unit` SMALLINT(6) NOT NULL DEFAULT 0,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NULL DEFAULT NULL,
`content` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_order_item_order` (`orderId` ASC),
CONSTRAINT `fk_order_item_order`
FOREIGN KEY (`orderId`)
REFERENCES `restaurant`.`order` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);

ALTER TABLE `restaurant`.`order_item`
ADD INDEX `idx_order_item_item` (`itemId` ASC);
ALTER TABLE `restaurant`.`order_item`
ADD CONSTRAINT `fk_order_item_item`
FOREIGN KEY (`itemId`)
REFERENCES `restaurant`.`item` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

Transaction Table

We also need a transaction table to track the order payments made by the guests to the restaurant and restaurant to the vendors for bookkeeping. We can also use the same table to record the credit(guests) and debit(vendors) transactions. Below mentioned is the description of all the columns of the Transaction Table.

IdThe unique id to identify the transaction.
User IdThe user id to identify the user associated with the transaction.
Vendor IdThe vendor id to identify the vendor associated with the transaction.
Order IdThe order id to identify the order associated with the transaction.
CodeThe payment id provided by the payment gateway.
TypeThe type of order transaction can be either Credit or Debit.
ModeThe mode of the order transaction can be Offline, Cash On Delivery, Cheque, Draft, Wired, and Online.
StatusThe status of the order transaction can be New, Cancelled, Failed, Pending, Declined, Rejected, and Success.
Created AtIt stores the date and time at which the order transaction is created.
Updated AtIt stores the date and time at which the order transaction is updated.
ContentThe column used to store the additional details of the transaction.

The Transaction Table with the appropriate constraints is as shown below.

CREATE TABLE `restaurant`.`transaction` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`userId` BIGINT NOT NULL,
`vendorId` BIGINT NOT NULL,
`orderId` BIGINT NOT NULL,
`code` VARCHAR(100) NOT NULL,
`type` SMALLINT(6) NOT NULL DEFAULT 0,
`mode` SMALLINT(6) NOT NULL DEFAULT 0,
`status` SMALLINT(6) NOT NULL DEFAULT 0,
`createdAt` DATETIME NOT NULL,
`updatedAt` DATETIME NULL DEFAULT NULL,
`content` TEXT NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `idx_transaction_user` (`userId` ASC),
CONSTRAINT `fk_transaction_user`
FOREIGN KEY (`userId`)
REFERENCES `restaurant`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION);

ALTER TABLE `restaurant`.`transaction`
ADD INDEX `idx_transaction_vendor` (`vendorId` ASC),
ADD INDEX `idx_transaction_order` (`orderId` ASC);

ALTER TABLE `restaurant`.`transaction`
ADD CONSTRAINT `fk_transaction_vendor`
FOREIGN KEY (`vendorId`)
REFERENCES `restaurant`.`user` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
ADD CONSTRAINT `fk_transaction_order`
FOREIGN KEY (`orderId`)
REFERENCES `restaurant`.`order` (`id`)
ON DELETE NO ACTION
ON UPDATE NO ACTION;

Address Table

An address table can be used to avoid the redundant columns in the Booking and Order table depending on the actual implementation. It can be directly mapped to the Booking Table and Order Table using the appropriate foreign keys.

Summary

In this tutorial, we have discussed the database design of a Restaurant Ordering System or Food Ordering System to store the users, book tables, automate kitchen, and manage product inventory. The same database schema can be used to accept online table booking and pre-orders. The database schema provided in this tutorial can be considered as the starting point and further optimized or updated based on the actual needs. The On-Premises Restaurant Ordering System Flowchart can be referred to implement the restaurant order system.

You may submit your comments to join the discussion. You may also be interested in designing the database of the Blog, Online Shopping Cart, and Poll & Survey applications. The complete database schema is also available on GitHub.

Share this blog:

Profile picture for user bhagwatchouhan
bhagwatchouhan