GAE/J 中的数据库设计:关系建模与实体属性值
想象一下,您计划创建一个在 GAE/Java 上运行的社交网络,其中每个用户都有一组属性(即年龄、当前城镇、兴趣)。
替代方案 1:经典方法 - user_id 和每个属性作为“行”
entity property_1 property_2 property_3
------ ---------- ---------- -----------------
bob missing NY [football, books]
tom 34 missing [books, horses]
替代方案 2:实体属性值 (EAV)
entity attribute value
------ --------- -----
bob town NY
bob interests [football, books]
tom age 34
tom interests [books, horses]
您认为每个选项的优点/缺点是什么有?我主要关心的是:
- 对多标准搜索有什么影响(即“给我提供居住在纽约且喜欢书籍的 45 岁以下用户”)
- 它会对 GAE/J 产生什么影响? (即索引、数据存储大小...)
- 如果要检索“喜欢书籍的用户”,如何使用多个值(例如“兴趣”)对属性进行建模?
我认为第二种选择更灵活,也许更容易实现,但我想知道其他有经验的开发人员的想法。
谢谢。
Imagine you plan to create a social network running on GAE/Java where each user has a set of properties (i.e. age, current town, interests).
Alternative 1: classical approach - the user_id and every property as a "row"
entity property_1 property_2 property_3
------ ---------- ---------- -----------------
bob missing NY [football, books]
tom 34 missing [books, horses]
Alternative 2: entity-atributte-value (EAV)
entity attribute value
------ --------- -----
bob town NY
bob interests [football, books]
tom age 34
tom interests [books, horses]
What pros/cons do you think each option has? My main concerns are:
- What is the impact on multi-criteria searches (i.e. "give me the users with ages under 45 that live in NY and like books")
- What GAE/J implications could it have? (i.e. indexes, datastore size...)
- How to model attributes with multiple values ("interests" for example) if you want to retrieve "users that like books" ?
I think the second alternative is more flexible and maybe easier to implement, but I would like to know what other experienced developers think.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您是否看过在 App Engine 上构建可扩展的复杂应用程序?该视频的音质很差,但涵盖了您的主题。他谈论了列表属性和合并连接及其局限性。
Did you have a look at Building Scalable, Complex Apps on App Engine from Google I/O 2009? The video has terrible sound-quality, but it covers your topics. He talks about list properties and merge-joins and their limitations.
如果 EAV 的灵活性对您的应用程序至关重要,那么就使用它,否则就不要使用它,因为它在查询时会遇到陷阱。
将返回所有拥有兴趣书籍的实体:
尝试获取拥有兴趣书籍且年龄在 45 岁以下的实体,但不会产生任何结果,因为没有行具有
a
和两个值>v
:结果并不令人意外,因为大表中的查询甚至无法接近 SQL 的灵活性(例如没有连接)。可行的解决方案可能是多个查询并手动组合和解析它们的结果。
OTOH 使用“经典方法”,这很简单:
这将打印出汤姆的数据。
If the flexibility of EAV is essential for your app then use it, otherwise do not since it'll have pitfalls in querying.
Will return all entities that have books in interests:
Trying to fetch entities that have books in interests and aged under 45, but won't result anything since no row will have the two values of
a
andv
:The result isn't surprising, as the querying in big table is not even close to the flexibility of SQL (no joins for example). The working solution would probably be multiple queries and manually combining and parsing their results.
OTOH with "classical approach" it's trivial:
This will print out tom's data.