PHP和DB设计:将数据存储在多个表中并合并或复制数据
我正在构建一个应用程序,其中每个用户都会拥有一堆项目。当用户注册时,大约 150 个用户特定项目将从模板表中添加到每个用户的表中。
逻辑如下:(复制)
用户注册
将 150 个模板项(行)从 template_table 复制到 userItems_table
显示 userItems_table 中的项目
用户可以在 Web UI 中按照自己的意愿更改其项目(名称、价格、颜色)。还添加新的,删除现有的等。
现在的问题是..而不是将 150 行复制到用户项目表中。我可以只使用模板表,当用户访问 UI 中的项目时,我会执行两个 select 语句,然后在 PHP 中合并两个数组以获得用户特定的项目。
逻辑如下:(叠加)
用户注册
如果用户更改项目,请将差异存储到 userItems_table
选择 template_table 和 userItems_table 到两个数组中,用算法合并数组
显示合并数组中的项目
该应用程序预计每周将增加约 20 个用户。所以一年内将会有大约 1000 名活跃用户。相当于每年至少 150.000 行加上一些用户特定的更改。他们经常在应用程序中访问这些项目,但不会经常更改。读取比率远高于写入比率。
我的目标是为此提供可持续且可扩展的设计..因为应用程序中的许多其他功能都依赖于访问用户项目列表。
这样做的最佳方法是什么?有什么创意吗?
谢谢!
附加信息:
- 使用的数据库是 MySQL 5.1,带有 InnoDB
- 模板项在应用程序的生命周期内不会改变。
I'm building an application where every user will have a bunch of items. When a user signs up about 150 user specific item are added into a table for every user from a template table.
Logic as follows: (copy)
User signs up
Copy 150 template items (rows) from template_table to userItems_table
Display items from userItems_table
The user can change his items (name, price, color) as he wishes in the web UI. Also add new ones, delete existing ones etc.
The question is now.. instead of copying the 150 rows to a user items table.. I could instead just use the template table and when a user accesses the items in the UI I'd do two select statements, then in PHP merge the two arrays to get the users specific items.
Logic as follows: (overlay)
User signs up
If user changes an items, store the diff into userItems_table
Select template_table and userItems_table in to two arrays, merge the arrays with an algorithm
Display items from the merged array
The application is expected to grow with around 20 user per week. So in a year there will be around 1000 active users. Equaling at least 150.000 rows per year plus a number of user specific changes. They access the items frequently in the App but they are not changed often. Read ratio a lot higher than write ratio.
My objective is to have a sustainable and scalable design for this.. because a lot of other functions in the app depends on accessing a users item list.
What is the best way of doing this? Any creative ideas?
Thanks!
Additional info:
- Database used is MySQL 5.1 with InnoDB
- Template items will not change during the lifespan of the application.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一种版本是您制作模板集的副本,另一种方式是您设置一个“覆盖”,其中每个人都共享该模板,除了他们已更改或更改的内容之外。额外。
一些需要考虑的讨论点。
性能:在复制版本中,用户转到一张表来获取他们需要的内容(= 1 个表命中)。在 Overlay 版本中,您始终必须访问两个表,首先获取用户输入的内容,然后获取用户未输入的内容(= 2 个表命中,根据 @Renderlin 的空检查算法)。
随着时间的推移模板修改:在 T 时间和 N 个用户之后,您决定向模板添加一些项目时会发生什么。在复制版本中,现有用户不会获得新项目,而在覆盖版本中,每个用户都会立即获取该新项目。同样,如果您选择更改(或删除)模板项目,如果用户从未修改过该项目,则会立即为他们修改该项目。
我没有足够的信息来判断什么是有效的,什么是无效的——这必须根据您的业务需求来确定。
One version, you make copies of the template set, the other way, you set up an “overlay”, where everyone shares the template except for what they’ve changed or added.
Some discussion points to consider.
Performance: In the Copy version, users go to one table to get what they need ( = 1 table hit). In the Overlay version, you always have to go to both tables, first to get what the users’s entered, then to get what they haven’t entered (= 2 tables hits, as per @Renderlin’s null-checking algorithm).
Template Modification over time: what happens when, after T time and N usrers, you decide to add some items to the template. In the Copy version, existing users do not get the new items, while in the Overlay version every user immediately picks up that new item. Similarly, if you choose to change (or drop) a template item, if the user has never modified the item, it is immediately modified for them.
I’ve insufficient information to figure what’s effective and what's not--this must be determined based on your business requirements.
假设您选择保留模板表,然后仅将用户自定义的项目的记录放入用户表中...不如将模板与用户更改的项目合并,而是执行左外连接。
例如
,
NVL
是一个 oracle 函数,它返回第一个参数,除非它为 null,在这种情况下,它返回第二个参数。如果您不使用 Oracle,您仍然可以使用case
语句或使用数据库的某些专有函数来获得相同的功能。这样,返回的每条记录都是用户的覆盖项(如果存在),否则是模板项(假设
user_item_table
中不允许有空值...如果是这样,那么您需要更改查询而不是对每一列执行nvl
,但检查user_item_table
中的主键是否为null
...如果不是,则从user_item_table
中获取所有值。Assuming you go with the option of keeping a template table and then only putting records in the user table for the items that user customized... how about instead of merging the template with the items the user changed, instead do a left outer join.
e.g.
NVL
is an oracle function that returns the first parameter unless it is null, in which case it returns the second. If you don't use oracle you can still get this same functionality using acase
statement or using some proprietary function of your database.That way every record coming back is the user's overridden item if it exists, else the template one (assuming no null values are allowed in the
user_item_table
... if so, then you need to change the query not to donvl
on each column but to check if the primary key in theuser_item_table
to see if it isnull
... if not, then take all the values from theuser_item_table
.