我已经使用了mysql一段时间了,但从来没有做过任何接近复杂的事情。我正在开发一个新项目,需要朝着正确的方向努力。让我们说我想要一张存放猫的桌子。让我们说我想存储猫的名字和猫喜欢的食物。然后我想说我想查询所有喜欢鱼,牛奶和老鼠的猫。我不希望'猫'表有'鱼''牛'老鼠'的行,可以是是或否或1或0.我想我想要的是有一个单独的'食物'表然后使用join语句。但我不知道从哪里开始寻找或搜索什么。考虑这个问题的另一种方法是,如果你有一个博客,并希望帖子有类别。我如何存储哪些帖子属于哪些类别,以及如何按类别查询帖子?
我意识到这可能是一个非常基本的问题,并且即使是指向解释所需结构/命令的教程的链接也会很高兴!非常感谢!
答案 0 :(得分:3)
Table: cats
id
name
Table: foods
id
name
Table: cat_food
cid (Cat ID)
fid (Food ID)
Query: Select cats that like fish
SELECT
name
FROM
cats c
INNER JOIN
cat_food cf
ON
cf.fid = 2 -- Assuming food ID#2 is 'fish'
Query: Select cats that like fish, milk, or mice
SELECT
c.name
FROM
cats c
INNER JOIN
cat_food cf
ON
cf.fid IN (1, 2, 3)
GROUP BY
c.name
SCHEMA
CREATE TABLE IF NOT EXISTS cats
(
id
int(10) unsigned NOT NULL AUTO_INCREMENT,
name
varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ;
INSERT INTO cats
(id
, name
) VALUES
(1, 'Sassy'),
(2, 'Tiger');
CREATE TABLE IF NOT EXISTS cat_food
(
cid
int(10) unsigned NOT NULL COMMENT 'Cat ID',
fid
int(10) unsigned NOT NULL COMMENT 'Food ID',
UNIQUE KEY cid_fid
(cid
,fid
),
KEY fid
(fid
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO cat_food
(cid
, fid
) VALUES
(1, 1),
(2, 2),
(1, 3);
CREATE TABLE IF NOT EXISTS foods
(
id
int(10) unsigned NOT NULL AUTO_INCREMENT,
name
varchar(255) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=4 ;
INSERT INTO foods
(id
, name
) VALUES
(1, 'Fish'),
(2, 'Milk'),
(3, 'Mice');
ALTER TABLE cat_food
ADD CONSTRAINT cat_food_ibfk_2
FOREIGN KEY (fid
) REFERENCES foods
(id
) ON DELETE CASCADE,
ADD CONSTRAINT cat_food_ibfk_1
FOREIGN KEY (cid
) REFERENCES cats
(id
) ON DELETE CASCADE;
答案 1 :(得分:1)
你正在思考。你想要两个表,一个“猫”表和一个“食物”表。您的Food表将具有某种主键,您的Cats表将引用该主键作为外键。你可以这样做一个查询:
SELECT * FROM cats WHERE food_id = 5
要了解JOIN在SQL中的工作原理,我会查看here。
答案 2 :(得分:1)
我只能提供rails示例。
在rails中
我是一个完美的世界,每个帖子都有一个类别
你会看到像
这样的SQLPosts.find_all_by_category_id(Category.find_by_topic("sports").id)
# May generate
SELECT ALL from `post`.* WHERE `category_id` = `7`
class Category < ActiveRecord::Base
has_many => :posts
end
class Post < ActiveRecord::Base
belong_to => :categories
end
在现实世界中它有多对多的关系
class Category < ActiveRecord::Base
has_and_belongs_to_many => :posts
end
class Post < ActiveRecord::Base
has_and_belongs_to_many => :categories
end
和rails会让你背后的多对多联接表
然后你会去Category.find_by_topic(“sports”)。帖子来恢复所有带有体育类别的帖子。
我不知道我的头脑中生成的详细的mySQL是如何做多对多关系的。