数据库设计,在这种情况下我应该使用varchar作为主键吗?

时间:2012-03-19 17:48:42

标签: database database-design

我正在构建一个网页,用户可以在其中创建帐户,每个帐户都有自己的子域名。所以可能会有这样的URL:

www.user1.domain.com
www.user2.domain.com
...

他们也有自己的页面,如下所示:

www.user1.domain.com/url-1/
www.user1.domain.com/url-2/
www.user2.domain.com/url-3/
...

所以我需要将account_url和page_url存储在数据库中。

我是这样做的,我有用户,帐户和页面表。

这就是我的表格的样子:

USERS:

user_id     PK
user_name
user_pass
...

帐户:

account_id  PK
user_id     FK
account_url
account_name
account_type
...

PAGES:

page_id     PK
user_id     FK
page_url    
page_name
page_content
...

现在问题是这个,因为我得到这样的网址:

www.user1.domain.com/page-url/

我可以从url获取的唯一信息是account_url和page_url,因为它在URL中,调度程序/路由器获取这两个变量。 account_url是子域名,page_url是域名之后的段。

由于将有多个用户,我总是需要获取user_id,以便我可以更新/删除属于它们的行。所以我需要更新page_content,其中user_id属于这个用户,page_url是来自URL的。

但我没有user_id。当我想更新page_url_content时,首先我需要找到user_id,如下所示:

SELECT user_id FROM accounts WHERE account_url = something 

然后当我有user_id时,我可以更新页面内容或执行任何其他操作。

这是一个好的设计吗? 它的规范化和干净,但是当我在控制器内的每个动作中使用它时,我需要首先获取user_id,以便能够进行我想要的真实查询。

现在,我可以将account_url用于主键,并使所有表与该主键相关。因此,当我获得URL时,我已经知道了主键,因为它在URL中。

这是在URL中使用主键的好例子,还是我做错了什么?

3 个答案:

答案 0 :(得分:2)

我更喜欢将主ID ID作为连接的整数。也就是说,有很多方法可以帮助您的网站变得活泼。

  • 您可以为account_url列编制索引,以便查找更有效。
  • 或者您可以对用户ID进行cookie并使用该值,而不是每次都查询数据库。当然,你会想做一些会话跟踪,所以有人不能欺骗别人。
  • 假设用户将控制子域的名称,因此将用户ID嵌入子域名可能不会有效,否则它也是一个选项。
  • 您可以将用户ID和用户account_url保存在一个单独的表中,并缓存该表,这样就不会在绝大多数查找中访问数据库。

我的建议是保持主键为整数,索引account_url并识别页面加载目标时间;说在1.500秒内完成所有数据库访问和页面呈现。当您的网站开始响应超过您的阈值时,您可以分析您的网站,看看实际问题在哪里,然后解决它们。

答案 1 :(得分:1)

通常,尽可能使数据库标准化。如果您出于性能原因可以证明(使用指标和实际测量)您需要进行非规范化,那么认为是关于这样做的。

在这种情况下,如果域与用户帐户之间存在m-1关系,则可以有效地将域视为用户ID;你只需要以正确的方式加入事物。 (并且通过m-1,我的意思是单个域只能由1个用户“拥有”)。

关键是你没有需要来获取user_id,因为你可以根据需要加入ACCOUNTS表,因为它将域绑定到user_id。

最后,关于使用域作为主键的问题,可以执行此操作,因为域需要“唯一”,但您的开销最小,灵活性更高通过使用代理主键。

答案 2 :(得分:0)

你有两个完全不同的问题。将子域和页面映射到用户更容易。更困难的问题是“国家”。您需要创建状态数据库(或类似模块)以跟踪当前登录的用户以及在收到更新时是否仍然登录。

JZ在他的评论中谈到了这一点。不要混淆这两个问题,它们是分开的,应该妥善处理。