我在MySQL工作,但这是一般的关系数据库查询。
我们有一个博客CMS,用户可以在上线后更改博客的网址,我们希望将任何旧博客网址改为301。
我在以下两个表选项之间被撕裂(所有字段都是NOT NULL):
选项1 - 带主标志的HAS_MANY
url
博客
缺点:博客没有或有多个主网址时可能存在完整性问题。
优点:许多或一个人的关系结构相似。
选项2 - HAS_MANY和BELONGS_TO混合
url
博客
缺点:博客的url_id和url的blog_id不匹配可能存在诚信问题。
优点:保证每个博客有一个主要网址。
有没有人对这些选项中的任何一个有任何经验,或者可以考虑使用/折扣其中一个或另一个的任何其他理由?或者可能是更好的第三种选择?
更新
刚刚意识到,如果不在网址的blog_id或博客的url_id中允许使用NULL,则选项2无法进行INSERT。
答案 0 :(得分:1)
而不是上述内容,我会考虑这样的事情:
博客
URL
在这种情况下,redirect_url_id是从url表到其自身的自引用外键。如果网址需要重定向,您可以在此列中添加重定向所需网址的ID。
这样可以避免您在列出的两个选项中注意到的缺点。唯一的缺点是,对于主URL,您只需将redirect_url_id保留为NULL,但这是可以接受的。
无论你做什么,绝对要避免选择2,两个方向的键都是 - 正如你所注意到的那样 - 不可行。
答案 1 :(得分:1)
如果我理解正确,博客通常会有一个网址,它可能会随着时间而改变。您希望保留旧URL,并重定向它。这可能会发生几次,并且可能有几个旧的URL。有时博客没有活动的URL,但它从来没有两个。
让我们从博客开始吧,因为这是我们关心的事情。
create table blog
( id ... primary key
, url ... unique
);
现在捕获旧网址:
create table url
( blog_id ...
, url ...
, primary key (blog_id, url)
, foreign key (blog_id) references blog(id)
);
如果blog.url
必须为NULL,那就没问题。您只需要处理这样一种可能性:当您将url加入博客时,您可能会获得一个NULL URL来重定向到。使用coalesce
的绝佳机会。 ; - )
在您的设计中,据我所知,url.id
没有任何实际意义。博客与其URL不同,因此可能需要ID。旧的URL,OTHO,只属于他们曾经属于的博客。给他们一个ID只是给你另一个数字来拖延。
答案 2 :(得分:1)
由于似乎没有关于URL的任何其他数据,为什么要将它放在一个单独的表中?
table blog
id (PK)
url (unique)
...other_fields..
但是,URL数据可能会发生变化,您希望随时跟踪这些更改。太好了,现在你有理由将它移到一个单独的表中:
table blog
id (PK)
...other_fields..
table URLs
blogID
url
EffDate
Primary key( blogID, url, EffDate )
使用当前网址显示博客数据:
select b.ID, u.url, b.* -- the other fields
from blog b
join URLs u
on u.blogID = b.ID
and u.EffDate = (
select Max( EffDate )
from URLs u2
where ur.blogID = b.ID
and ur.EffDate <= @today )
where b.ID = @MyblogID;
这个查询的好处是,要查看过去任何特定日期的网址,只需将@today
替换为您感兴趣的日期。
由于您的应用可能主要对当前网址感兴趣,因此请使用不带where
子句的查询创建视图。对于当前的URL,查询将是:
select *
from Current_blogs
where ID = @MyblogID;