你很可能和得太多了过于复杂的问题。坚持使用名为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