简体   繁体   English

MySQL DB设计帮助

[英]MySQL DB design help

Pardon the elementary question but my newness to the realm of database design leaves me in a bind quite often. 原谅这个基本问题,但我对数据库设计领域的新面貌让我经常陷入困境。

I have a site that keeps growing with regard to families of information. 我有一个关于信息家庭不断增长的网站。 In the beginning I had one sort of item I was describing and all was well. 一开始我有一种我描述的项目,一切都很顺利。 That item occupied one record and had 34 columns (a lot now that I look back) attributed to it of descriptive data. 那个项目占据了一个记录,并且有34列(现在很多我回头看)归因于描述性数据。 As I get more and more into this stuff, I see that many developers break out data (when practical) into distinct tables. 随着我越来越多地了解这些内容,我发现许多开发人员将数据(实际上)分解为不同的表。

I've now got additional tables that relate to the original item but are not always needed when describing the original item so I broke them out so they're not queried unnecessarily. 我现在已经有了与原始项目相关的其他表格,但在描述原始项目时并不总是需要这些表格,所以我将它们分解出来以便不会被不必要地查询。

Anyhow, I have a new item I've been trying to organize which is a USER. 无论如何,我有一个新项目,我一直在尝试组织一个用户。 The user table has typical columns like username, email, last_login, path to associated image, etc. These users have been making comments, which I keep in yet another table that contains columns with IDs that relate to the user and the item on which they are commenting. 用户表具有典型的列,如用户名,电子邮件,last_login,相关图像的路径等。这些用户一直在制作评论,我在另一个表中包含了包含与用户及其所在项目相关的ID的列正在评论。

Now... I am in the process of adding the obligatory user profile page to the site. 现在......我正在将强制性用户个人资料页面添加到网站。 Should I create yet another table containing only essential profile data or append the existing user record with profile data in the original user table? 我是否应该创建另一个仅包含基本配置文件数据的表,或者在原始用户表中附加包含配置文件数据的现有用户记录? I am thinking housekeeping might be a pain if I am to add a "Remove me from site" function as I would have to run something that kills the user record, the user profile record, and any other data associated with that user ID in other tables. 我想如果我要添加一个“从站点中删除我”功能,家务可能会很痛苦,因为我必须运行杀死用户记录,用户配置文件记录以及与其他用户ID关联的任何其他数据的东西。表。

Basically what I am asking is should I keep going with this "granular" design method - breaking everything out into essential parts or does it ever serve me to consolidate into larger tables? 基本上我要问的是,我应该继续使用这种“细化”的设计方法 - 将所有内容分解为必要部分,还是将它整合到更大的表中? I see a few instances where if a user deletes their account, I'll be left with a bunch of non-relevant data. 我看到一些情况,如果用户删除了他们的帐户,我将留下一堆不相关的数据。 For instance, the original item are restaurants... if I make a table to record "Visits" to restaurants, containing the Restaurant ID and the User ID, if the user or restaurant get removed from the site, this "Visits" table will have a bunch of useless records saying either "non existent restaurant was visited by user 45" or "Restaurant 21 was visited by non-existent user" 例如,原始项目是餐馆...如果我创建一个表来记录餐馆的“访问”,包含餐馆ID和用户ID,如果用户或餐馆从网站上删除,这个“访问”表将有一堆无用的记录说“用户45访问过不存在的餐馆”或“餐馆21被不存在的用户访问过”

I hope I make sense here... I'm just wondering if it's normal to end up with this "junk" data over time. 我希望我在这里有意义......我只是想知道随着时间的推移结束这个“垃圾”数据是否正常。

Thanks much, Rob 非常感谢,Rob

Deleting that "on-relevant" data is a normal, healthy part of an application's life. 删除“相关”数据是应用程序生命中正常,健康的一部分。 It's just what happens. 这就是发生的事情。 You just have to do it, like you brush your teeth or make your bed. 你必须这样做,就像你刷牙或铺床一样。 Don't let two or three DELETE queries influence how your tables get structured. 不要让两个或三个DELETE查询影响表的结构。 They're not that expensive, and honestly, if you think that's too much of a pain, you're in the wrong business :) 它们并不贵,老实说,如果你觉得这太痛苦了,那你就错了!:)

If you're using InnoDB tables, you can look into foreign key constraints that will take care of some of the cleanup for you. 如果您正在使用InnoDB表,则可以查看外键约束 ,这些约束将为您完成一些清理工作。

如果您了解规范化,您将能够更轻松地做出这些决定。

In general, if data all relates to the same logical entity -- the same "thing" -- then it should go in the same table. 通常,如果数据都与同一个逻辑实体相关 - 相同的“事物” - 那么它应该放在同一个表中。 Breaking one table into two just to keep the tables smaller is generally not a good idea. 为了保持表格更小,将一个表分成两个通常不是一个好主意。 Depending on what you are doing, it may or may not make queries faster, and it introduces unnecessary complexity. 根据您正在做的事情,它可能会或可能不会使查询更快,并且会带来不必要的复杂性。 Let me explain. 让我解释。

Whether it makes queries faster depends on the nature of the data and how you use it. 是否使查询更快取决于数据的性质以及如何使用它。 If you have some very large field, like "rambling_comments varchar(5000)" or some such, and it is rarely used, then breaking it into a separate table so that what's left in the "main" table is relatively small could indeed make your queries faster, for the fairly obvious reason that there is now less data to read. 如果你有一些非常大的字段,比如“rambling_comments varchar(5000)”或者其他一些,很少使用它,那么将它分成一个单独的表,以便“主”表中剩下的内容相对较小,这确实可以使你的查询速度更快,因为现在有更少的数据需要读取。 But if the size of the fields you are thinking of breaking out are modest, and you often need data from both tables, then queries that only use one table don't gain that much, and queries that use both now need to do a join, which is usually more expensive than reading a somewhat bigger record. 但是如果您想要突破的字段大小适中,并且您经常需要来自两个表的数据,那么仅使用一个表的查询不会获得那么多,而现在使用这两个表的查询需要进行连接,这通常比阅读更大的记录更昂贵。

But breaking up your tables will certainly make your programs more complex. 但分解你的表肯定会使你的程序更复杂。 Now you have to keep track of which data is in which table. 现在,您必须跟踪哪个表中的数据。 You'll constantly be checking if that field is in the Item_Descriptive_Data table or the Item_Stock_Data table or whatever. 您将不断检查该字段是否在Item_Descriptive_Data表或Item_Stock_Data表中或其他任何内容。 You're liable to lose track at some point and accidentally put the same field into two tables. 你可能会在某些时候失去踪迹,并且不小心将同一场放入两张桌子。 (Or worse, you'll decide this is a good idea and do it deliberately.) Then you have redundant and potentially contradictory data. (或者更糟糕的是,你会认为这是一个好主意并且故意这样做。)然后你就会有冗余且可能相互矛盾的数据。

You have to do joins every time you need data that crosses tables. 每次需要跨越表的数据时,都必须进行连接。 You create the possibility that records in one or more of the tables may not exist. 您可能会创建一个或多个表中的记录可能不存在的可能性。 Like, if you break your User table into User_Main and User_Profile, and you need data from both tables so you do a join, what happens if there is a record in User_Profile with no corresponding record in User_Main? 就像,如果你将User表分成User_Main和User_Profile,并且你需要来自两个表的数据以便你进行连接,如果User_Profile中有一条记录而User_Main中没有相应的记录会怎样? You're going to have to add code to check for the possibility and deal with it. 您将不得不添加代码来检查可能性并处理它。 Oh, and blithely saying "That can never happen, no need to worry about it" is a very dangerous attitude: No matter that it's not SUPPOSED to happen, sooner or later it will, and if you don't handle the error gracefully, you could have a real mess. 噢,快乐地说“那永远不会发生,不用担心它”是一种非常危险的态度:不管它是不是支持发生,迟早会发生,如果你不优雅地处理错误,你可能真的很乱。

In short, breaking up tables for performance reasons is usually a premature optimization. 简而言之,出于性能原因而拆分表通常是不成熟的优化。 If you find that you have some real performance problem, THEN look at the tables and see if you should denormalize for efficiency. 如果您发现自己有一些真正的性能问题,那么请查看表格,看看是否应该对效率进行非规范化。 But don't start out trashing your database just to avoid a problem that might possibly happen someday. 但是,不要只是为了避免可能在某天发生的问题而开始破坏数据库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM