你很可能和得太多了過於複雜的問題。堅持使用名爲id
的單個主鍵的AR成語。
對於連接表使用外鍵代替化合物PK。還要堅持命名規則,除非你想通過違反最小驚喜原則來看起來無能或惹惱其他開發者。這意味着:一切
- 使用
snake_case
(表名,列,索引名等)
- 沒有前綴的表名的列。它只是讓您的應用程序中的每個變量都變得更長,並且不需要在ORM中使用。對於外鍵列,使用
_id
。前;對於時間戳,使用_at
。前; confirmed_at
- 使用
thing_other_things
用於連接表,除非有一個更具描述性的名稱
而且許多情況下應該只使用一種間接的關係,加入了層次結構,而不是重複的外鍵。
這是一個例子DB模式:
ActiveRecord::Schema.define(version: 20161214013752) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "ingredient_types", force: :cascade do |t|
t.string "name"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "ingredients", force: :cascade do |t|
t.integer "ingredient_type_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["ingredient_type_id"], name: "index_ingredients_on_ingredient_type_id", using: :btree
end
create_table "recipe_ingredients", force: :cascade do |t|
t.integer "recipe_id"
t.integer "ingredient_id"
t.float "quantity"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["ingredient_id"], name: "index_recipe_ingredients_on_ingredient_id", using: :btree
t.index ["recipe_id"], name: "index_recipe_ingredients_on_recipe_id", using: :btree
end
create_table "steps", force: :cascade do |t|
t.integer "recipe_id"
t.integer "ordinal"
t.text "instruction"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["recipe_id"], name: "index_steps_on_recipe_id", using: :btree
end
create_table "recipes", force: :cascade do |t|
t.string "name"
t.string "description"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_foreign_key "ingredients", "ingredient_types"
add_foreign_key "recipe_ingredients", "ingredients"
add_foreign_key "recipe_ingredients", "recipes"
add_foreign_key "steps", "recipes"
end
class IngredientType < ApplicationRecord
has_many :ingredients
end
class Ingredient < ApplicationRecord
belongs_to :ingredient_type
has_many :recipe_ingredients
has_many :recipes, through: :recipe_ingredients
end
class RecipeIngredient < ApplicationRecord
belongs_to :recipe
belongs_to :ingredient
has_one :ingredient_type, through: :ingredient
end
class Step < ApplicationRecord
belongs_to :recipe
end
class Recipe < ApplicationRecord
has_many :recipe_ingredients
has_many :ingredients, through: :recipe_ingredients
has_many :steps
end
來源
2016-12-14 01:28:49
max
這不是我的確切模式,我只是用它作爲參考。但這些都是非常好的提示。我也不是專業的SQL數據庫設計師......你如何推薦不使用組合鍵來建模recipe_step_ingredients?一個配方有很多步驟,每一步都可以有很多成分,所以我很難找出一個簡單的模式來使用,而不涉及組合鍵。 –
它本身可能只是一種過度複雜化。您是否真的需要在步驟中儲存成分的數量,而不僅僅是在加入「食譜」和「成分」的連接表上? – max
大多數食譜都將成分列在一起,然後您只需在步驟中寫上「在蛋類中混合四分之一」的東西。吻。 – max