1

我将一头扎进一个我已经组建了一个小团队来制作的 SAAS 项目。在大多数情况下,我们已经对所有功能进行了明智的计划,但我现在需要开始考虑数据库架构和安全问题。

由于您可能拥有数百名用户,因此是否存在与普通 Web 应用程序项目不同的安全问题?

就数据库而言,我整天都在阅读有关数据库设计的帖子,我想我会为所有事情使用一个数据库,但我想知道这是否会变慢?假设您有一个“客户”表,其中包含 30,000 条记录。这不会比为每个客户做一个数据库慢得多吗?

此外,注册信息和我的客户信息是否应该与实际的 SAAS 应用程序位于同一数据库中。换句话说,访问我的网站并注册免费试用的用户应该进入一个数据库,而他的所有团队和客户等都进入实际的产品数据库,还是应该只是一个数据库?

在深入研究之前还有其他注意事项吗?我将在 Codeigniter 框架上构建它。

4

3 回答 3

4

这里有一些想法:

安全

你会从拥有更大用户群的潜在黑客那里得到更多的关注,但除此之外,你的安全问题应该是一样的,在大多数情况下(只是有人发现和利用安全漏洞的机会和后果要高得多)。

我不知道您对 Codeigniter 了解多少,但它内置了许多安全功能。还有您想要的任何网站的一般安全内容。

  • 考虑启用 CI 的跨站点脚本保护
  • 考虑使用 CI 的数据库会话
  • 正确使用 CI 的 Active Record DB 类避免 MySQL 注入漏洞
  • 确保您正在对密码进行散列和加盐(每个用户的盐都很好,还要确保您的散列算法是安全的 - 即,不是 MD5)
  • 还要确保以某种方式对任何其他机密信息进行加密 - Codeigniter 有一个为此提供的库,如果您的服务器上有 mcrypt 支持,这是不错的
  • 确保过滤用户输入以防止 XSS(跨站点脚本)攻击。Codeigniter 有一个功能可以尝试过滤掉这些,但是它的实现并不好
  • 确保权限检查是无懈可击的,这样用户就无法访问不属于他们的信息
  • 每个 ip 限制每小时实施某种登录尝试

表现

我在这里没有任何冷酷的数字可以给你,但一定要确保所有适当的字段都被索引,因为表扫描会随着行数的增加而变得非常慢。

避免过度规范化您的数据 - 有时将相同的数据存储在多个位置会更好。然后,更新数据会导致性能下降,但可能会在读取数据时节省连接时间。

如果有机会使用数据库触发器,那就去吧 - 它比让您的 Web 应用程序向数据库发送多个查询来完成同样的事情要快得多。

如果您将免费试用帐户隔离到另一个数据库中,这将有助于将“真实客户数据”与试用数据分开(并且更容易说,仅对非试用数据执行自动备份)。从基础架构的角度来看,如果您希望将免费试用和常规服务转移到单独的系统上,它也会变得更容易。

不过不要有太多数据库,请记住,每次推送更新时,您都需要确保每个数据库模式都是最新的并且满意。如果您有数百个客户端数据库,那么对它们进行任何类型的非自动化管理都可能很容易变成一场噩梦。

于 2013-05-04T10:00:23.040 回答
0

根据我使用 SaaS 的经验,每次访问时最好将数据保存在同一个数据库中。如果您使用的是 MySQL,那么每个数据库在任意时间可以打开多少表是有限制的。如果您使用包含大量表的大量数据库,您将遇到内存和 I/O 问题。我记得有一个项目,我们每个客户端有 1 个数据库,在 10 个客户端(每个客户端 30~40 个表)之后,我们在 4GB 服务器上达到了内存限制。

就像威廉说的那样,如果可能的话,你想避免过度规范化。您将希望在可能的情况下为对象属性实现 EAV 表,例如在用户表上,其中每个客户端可能具有每个站点的不同配置。用户角色、用户组等也是如此。如果您正在构建电子商务功能,您肯定会想要使用 EAV。对于普通网站,3NF就可以了;大多数重复数据被分离出来并与外键链接在一起,这样您就没有 20 - 30 列的表。对于 SaaS 应用程序,您可能需要将其提高到 4NF 的 BCNF,以便您允许额外的应用程序灵活性。

站点/应用程序确定:

为所使用的 URL 显示正确的网站至关重要。最简单的形式是使用 XML/JSON 文件并根据请求扫描 XML 文件以匹配 URL。尽可能将其缓存在内存中,因为您会发现每个新站点的流量都会呈线性增长。如果您有 3 个网站,那么您将获得 3 倍于一个应用程序的流量,而不是分散在三个不同的应用程序上。

安全:

这取决于您需要的安全级别。如果您需要 SSL 证书,如果您要托管来自同一 IP 的所有站点,则可以购买共享服务器证书。如果每个站点都想要自己的 SSL,那么您将不得不为站点提供不同的 IP。那是您需要映射 URL => IP 的时候。

基于用户的安全性与显示正确的站点同样重要。您需要确保您正在检测基于注入的攻击。您可以利用内置的 CI 功能,但为了安全起见,您应该进行自己的过滤。检查整数是否真的是整数。您可以向 CI 添加其他库来实现此目的。ACL 在 SaaS 应用程序中非常重要,因为您会希望限制谁可以看到什么,并且您将每个人限制在他们自己网站的内容中。它很容易概念化但很难实现,应该被认为是正确的第一开发任务。设计 ACL,测试设计,开发测试用例,如果可行,实施它。

表现:

CI 的性能非常好,重量轻,没有太多的内存占用。您将希望尽可能多地利用缓存 - 数据库、文件、APC、Memcache 等。请记住,数据库缓存总是比文件缓存快,但它会为数据库服务器创建更多套接字/tcp 请求. 如果数据库服务器出现瓶颈,则会影响站点性能。

在性能方面我会推荐一件事,看看使用几个不同的 Web 服务器并在你将运行的硬件上进行负载测试。好的选择是 Apache、Nginx 和 LiteSpeed。我以前用过 Apache 和 Nginx;它们在某些情况下都表现良好,如果您适当地调整它们,将能够毫不费力地处理大量流量。请记住,Nginx 配置与 Apache 不同,因此 htaccess 规则必须以 Nginx 格式编写并保存到站点配置中。您还将使用 php-fpm 而不是 suexec。如果您确实使用 Apache,请确保将 htaccess 规则保存到站点配置文件中,而不是使用根目录中的 .htaccess 文件。原因是文件统计会创建 I/O 请求,而大量 I/O 请求最终会造成瓶颈。

100% 尽可能使用应用程序级缓存,只需确保提前计划好关键索引,以便为每个客户端站点获取正确缓存的信息。一个好方法是散列站点名称,甚至使用 url 作为关键索引的一部分(例如 www_joeblogs_com_somekeyasdasd)。我知道一些 CMS 应用程序不这样做(Joomla),所以您将从另一个站点返回数据!

于 2013-09-07T02:50:34.433 回答
0

为 SaaS 应用程序使用单个数据库时要考虑的一件大事:

  • 将 accountId 添加到所有表中。
  • 在对数据库的所有查询中始终使用 accountid。否则,您最终可能会混淆帐户之间的数据。

此外,在决定为试用帐户和付费帐户设置单独的数据库之前,请考虑当试用帐户转换为付费帐户时会发生什么。他们肯定会想要保留所有数据。您是否要将他们的所有数据从试用数据库移动到付费数据库?

于 2013-05-14T17:01:31.733 回答