rubicon44TechBlog
    Search by

    Table Definition.

    created_at:July 09, 2022

    updated_at:July 10, 2022

    Today, I am going to explain physical design process.

    Purposes of this article creation

    • To be able to create DB tables in MySQL in Ruby on Rails on my own.
    • To be able to do physical design.

    Table Definition Process

    In this case, I will create physical data model for a SNS task management application on Cacoo as a deliverable.

    【What is Table Definition?】

    • Physically optimize the data model to match the DBMS to be used.
    • Implement a database by setting specific data types, constraints, etc.

    ※The state in which DB can be implemented by looking at the physical data model.

    【Table Definition Process】

    1. Determine Data Types (string, number, half-width alphanumeric characters)
    2. Assigning Constraints

    1. Determine Data Types (string, number, half-width alphanumeric characters)

    ※In this case, “db/schema.rb” in Rails is used as the deliverable.

    ※The “created_at” and “updated_at” columns, which are automatically created by Rails, are omitted.

    ※Be aware that using inappropriate data types may consume more disk space than necessary and may affect performance.

    ※Deliverable is introduced in “Deliverable(db/schema.rb)“.

    2. Assigning Constraints

    ※As in “1. Determining data types (strings, numbers, half-width alphabetic characters),” Rails’ “db/schema.rb” is used as the deliverable here.

    ※The “created_at” and “updated_at” columns automatically created by Rails are omitted.

    【Point】

    • Add appropriate constraints.

    [Types of constraints in Rails when creating tables]

    • 1.NOT NULL Constraint

      • Constraint that does NOT allow NULL (empty value) to be entered in the attribute values of a specific table.
    • 2.Uniqueness Constraint

      • Constraint that prohibits duplicate data in a table.
      • For example, when you do not want users to register with the same email address.
    • 3.Primary Key Constraint

      • Constraint that guarantee that the attribute value that is the primary key always exists and is not duplicated.
      • It is equivalent to setting both NOT NULL and Uniqueness Constraint on the primary key.
      • When creating tables in Rails, primary key constraint are originally implemented (primary keys are automatically created as id columns, and values in id columns are not duplicated).
    • 4.Foreign Key Constraint

      • Constraint that the corresponding record of a foreign key must also exist in the record of the parent table.
      • Even if a foreign key column has a value, there must be a record in another table that has that value as a primary key.
    • 5.DEFAULT Constraint

      • Constraint that have an initial value.

    ※In case of FK constraint, FK can be specified by Model relationship (belongs_to or has_many).

    【Deliverable】
    1.[users]

    [NOTNULL、More than 4 characters and less than 50 characters(Number of characters that can fit on the screen in an easy-to-read manner.)]    t.string "nickname", limit: 50, null: false
    [NOTNULL、Uniqueness]    t.string "email", null: false
    [NONE]    t.string "firebase_id"
    [NULL OK、Less than 160 characters]    t.string "bio", limit: 160
    [NOTNULL、Less than 15 characters、Uniqueness]    t.string "username", limit: 15, null: false
    ーーー
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["username"], name: "index_users_on_username", unique: true

    2.[tasks]

    [NOTNULL、"Untitled" will be automatically added on the backend side.]    t.string "title", null: false
    [NULL OK]    t.text "content"
    [NOTNULL、FK]    t.bigint "user_id", null: false
    [NOTNULL、Automatically add "unsupported (numeral 0)" on front or backend side.]    t.integer "status", null: false
    [NOTNULL、Specify date format.、Automatically add "date" on backend side.]    t.string "start_date", null: false
    [NOTNULL、Specify date format.、Automatically add "date" on backend side.]    t.string "end_date", null: false
    ーーー
    t.index ["user_id"], name: "fk_rails_4d2a9e4d7e"
    
    ※If neither is set, "today(start_date) & later(end_date)" is used.If only one of the two is set, "the date not set is the previous or later date" is used.

    3.[likes]

    [NOTNULL、FK]    t.bigint "task_id", null: false
    [NOTNULL、FK]    t.bigint "user_id", null: false
    ーーー
    t.index ["task_id"], name: "fk_rails_5b40312a1e"
    t.index ["user_id"], name: "fk_rails_1e09b5dabf"

    4.[relationships]

    [FK]    t.bigint "following_id"
    [FK]    t.bigint "follower_id"
    ーーー
    t.index ["follower_id"], name: "index_relationships_on_follower_id"
    t.index ["following_id"], name: "index_relationships_on_following_id"

    5.[notifications]

    [FK]    t.bigint "visitor_id"
    [FK]    t.bigint "visited_id"
    [FK]    t.bigint "task_id"
    [NOTNULL、DEFAULT("")]    t.string "action", default: "", null: false
    [NOTNULL、DEFAULT(false)]    t.boolean "checked", default: false, null: false
    ーーー
    t.index ["task_id"], name: "index_notifications_on_task_id"
    t.index ["visited_id"], name: "index_notifications_on_visited_id"
    t.index ["visitor_id"], name: "index_notifications_on_visitor_id"

    Deliverable(db/schema.rb)

    ActiveRecord::Schema.define(version: 2022_07_10_114648) do
      create_table "likes", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
        t.bigint "task_id", null: false
        t.bigint "user_id", null: false
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
        t.index ["task_id"], name: "fk_rails_5b40312a1e"
        t.index ["user_id"], name: "fk_rails_1e09b5dabf"
      end
    
      create_table "notifications", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
        t.bigint "task_id"
        t.string "action", default: "", null: false
        t.boolean "checked", default: false, null: false
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
        t.bigint "visitor_id"
        t.bigint "visited_id"
        t.index ["task_id"], name: "index_notifications_on_task_id"
        t.index ["visited_id"], name: "index_notifications_on_visited_id"
        t.index ["visitor_id"], name: "index_notifications_on_visitor_id"
      end
    
      create_table "relationships", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
        t.bigint "following_id"
        t.bigint "follower_id"
        t.index ["follower_id"], name: "index_relationships_on_follower_id"
        t.index ["following_id"], name: "index_relationships_on_following_id"
      end
    
      create_table "tasks", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
        t.string "title", null: false
        t.text "content"
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
        t.bigint "user_id", null: false
        t.integer "status", null: false
        t.string "start_date", null: false
        t.string "end_date", null: false
        t.index ["user_id"], name: "fk_rails_4d2a9e4d7e"
      end
    
      create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t|
        t.string "nickname", limit: 50, null: false
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
        t.string "email", null: false
        t.string "firebase_id"
        t.string "bio", limit: 160
        t.string "username", limit: 15, null: false
        t.index ["email"], name: "index_users_on_email", unique: true
        t.index ["username"], name: "index_users_on_username", unique: true
      end
    
      add_foreign_key "likes", "tasks"
      add_foreign_key "likes", "users"
      add_foreign_key "notifications", "tasks"
      add_foreign_key "notifications", "users", column: "visited_id"
      add_foreign_key "notifications", "users", column: "visitor_id"
      add_foreign_key "relationships", "users", column: "follower_id"
      add_foreign_key "relationships", "users", column: "following_id"
      add_foreign_key "tasks", "users"
    end

    References

    [Table Definition]

    [Data Types in Rails]

    [Table Column Constraint in Rails]

    [Not Null Constraint]

    [Text Limit Constraint]

    [FK Constraint]

    [Table Index]

    [Others]

    Summary/What I learned this time

    Since table definitions are the basis for creating services, they should be created correctly to prevent defects and to make them easy to use for users and developers.
    I would like to be able to design tables more appropriately through repetition of “creating new tables,” “reviewing the initial table design after the service start,” “modifying existing tables,” and so on.
    I would like to become a higher level developer by accumulating small efforts one by one.

    © 2022, rubicon44TechBlog All rights reserved.