diff --git a/diet.py b/diet.py
new file mode 100644
index 0000000000000000000000000000000000000000..8b3e99b42a1a8d5b4096fab77988642007b1a223
--- /dev/null
+++ b/diet.py
@@ -0,0 +1,61 @@
+from sqlalchemy import create_engine, Column, Integer, String, DateTime, ForeignKey
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.orm import sessionmaker, relationship
+
+
+Persisted = declarative_base()  # pylint: disable=invalid-name
+
+
+class User(Persisted):
+    __tablename__ = 'users'
+    user_id = Column(Integer, primary_key=True)
+    name = Column(String(256), nullable=False)
+    meals = relationship('Meal', uselist=True, back_populates='user')
+
+
+class Meal(Persisted):
+    __tablename__ = 'meals'
+    meal_id = Column(Integer, primary_key=True)
+    user_id = Column(Integer, ForeignKey('users.user_id', ondelete='CASCADE'), nullable=False)
+    timestamp = Column(DateTime, nullable=False)
+    user = relationship('User', back_populates='meals')
+    meal_food_types = relationship('MealFoodType', uselist=True, back_populates='meal')
+    food_types = relationship('FoodType', uselist=True, secondary='meal_food_types', viewonly=True)
+
+
+class FoodType(Persisted):
+    __tablename__ = 'food_types'
+    food_type_id = Column(Integer, primary_key=True)
+    name = Column(String(256), nullable=False)
+    meal_food_types = relationship('MealFoodType', uselist=True, back_populates='food_type')
+    meals = relationship('Meal', uselist=True, secondary='meal_food_types', viewonly=True)
+
+
+class MealFoodType(Persisted):
+    __tablename__ = 'meal_food_types'
+    meal_id = Column(Integer, ForeignKey('meals.meal_id', ondelete='CASCADE'), primary_key=True)
+    food_type_id = Column(Integer, ForeignKey('food_types.food_type_id', ondelete='CASCADE'), primary_key=True)
+    amount = Column(Integer, nullable=False)
+    meal = relationship('Meal', back_populates='meal_food_types')
+    food_type = relationship('FoodType', back_populates='meal_food_types')
+
+
+class DietDatabase(object):
+    @staticmethod
+    def construct_mysql_url(authority, port, database, username, password):
+        return f'mysql+mysqlconnector://{username}:{password}@{authority}:{port}/{database}'
+
+    @staticmethod
+    def construct_in_memory_url():
+        return 'sqlite:///'
+
+    def __init__(self, url):
+        self.engine = create_engine(url)
+        self.Session = sessionmaker()  # pylint: disable=invalid-name
+        self.Session.configure(bind=self.engine)
+
+    def ensure_tables_exist(self):
+        Persisted.metadata.create_all(self.engine)
+
+    def create_session(self):
+        return self.Session()