存储用户并传入单个表或单独的表

Posted

技术标签:

【中文标题】存储用户并传入单个表或单独的表【英文标题】:store users and pass in single table or separate table 【发布时间】:2012-10-30 15:28:17 【问题描述】:

我想为我的网站创建一个用户管理系统,

什么对安全性和性能更好。

类型 1:

table_user : user_id , user_name , user_email , user_password . user_phone ...

类型 2:

table_user : user_id , user_name , user_email ...
table_pass : user_id , user_password .
table_phone: user_id , user_phone .

哪个更好?

【问题讨论】:

第一个,前提是您不存储明文密码而是哈希值 【参考方案1】:

这取决于。如果您想保留密码历史记录并且如果用户可以拥有许多电话号码,那么您可以为密码和电话创建额外的表格。在其他情况下,一张桌子就足够了。

【讨论】:

【参考方案2】:

首先,作为@Steve cmets,您应该使用安全的散列机制存储密码——存储纯文本密码是不负责任的——这意味着任何可以侵入你系统的人都知道他们可能在其他网站上重复使用的用户密码.

其次,这两种设计都没有内在的安全性或性能优势 - 从安全性的角度来看,您必须假设可以访问您的数据库的攻击者可以运行查询,并且很容易检索两种方案中的数据。从性能的角度来看,如果您有主/外键索引,则选项 2 中的连接成本不太重要。

如果您需要在一段时间后重新设置密码,并且您需要存储密码历史记录以防止人们重复使用密码(例如,这是 Windows 支持的功能),您需要去有一个“ UserPassword”表,包含 valid_from 和 valid_until 列。

【讨论】:

【参考方案3】:

我会选择选项 1。

想想有成千上万的用户。因此,要获取用户数据,您将不得不处理 n 个表而不是 1 个表,这显然会在服务器上添加 LOAD,最终您将获得 BAD PERFORMANCE。

所以,我会选择选项 1。

电话。 number,将字段添加为landline_number,mobile_number,alternate_number 作为在表中添加字段不会产生太大的区别,然后为字段添加表。

是的,根据史蒂夫的评论,使用安全散列机制存储密码。

那么你会选择什么选项呢?

【讨论】:

一个!但是如果我们丢失了第一张桌子会发生什么,我们会丢失所有信息 好的,如果您在选项 2 中丢失了第一张桌子,您会怎么做? @Ata : 我希望你的问题得到答案but what happen if we lost table one , we lose all information :D :P 如果我回答你的问题,请接受答案【参考方案4】:

理想情况下:

根本不存储密码(即使是加密的)。存储源自密码的哈希。 Salt 用于防止rainbow attacks 的密码。 将哈希放在单独的数据库服务器上,位于其自己的防火墙和自己定义良好的 API1 后面。这个 API 应该只做三件事:
    对于给定的用户名,检索相应的密码哈希。 对于给定的用户名,设置新的哈希(以支持重置密码)。 删除给定的用户名及其哈希(以支持用户注销)。
对 salts 执行相同操作:将它们放在自己的服务器上并在自己的防火墙和 API 后面。这个 API 应该只做三件事:
    对于给定的用户名,检索相应的盐。 对于给定的用户名,将新盐设置为随机值(以支持重置密码)。 删除给定的用户名及其盐(以支持用户注销)。
哈希服务器和盐服务器都应该与世界(以及彼此)断开,并且只能从运行您的 Web 应用程序的服务器(即 php 或 ASP.NET 或其他...)访问。

当用户尝试通过输入用户名和密码登录时:

确保这是通过 HTTPS 完成的,以便输入的数据安全地到达您的服务器。 调用检索用户名密码哈希的 API。 调用检索用户名 salt 的 API。 对用户输入的密码进行加盐和哈希处理,并将其与检索到的哈希值进行比较。 如果匹配,则授予用户访问权限。

就其本质而言,哈希是不可逆的——除了用户之外,没有人知道确切的密码,甚至你也不知道。如果用户忘记密码,您不能将密码发送给他们,但您可以允许他们重置密码,前提是他们通过了一些额外的验证(即可以访问特定的电子邮件地址和/或回答秘密)问题)。

顺便说一句,登录是相对很少见的操作,因此除非您完全忽略正确的索引,否则不太可能造成性能瓶颈。


1实现一个 Web 服务,然后只打开该 Web 服务所需的端口,而不打开其他任何东西。

【讨论】:

以上是关于存储用户并传入单个表或单独的表的主要内容,如果未能解决你的问题,请参考以下文章

用于存储 Int 浮点数和日期的用户定义数据类型

数据绑定到具有角度本地存储数据的表

MySQL存储过程语句及调用

MySQL存储过程语句及调用

使用单个查询插入多行时获取所有插入的 ID

如何使用单个PHP代码在单独的字段中存储单独的图像