简体   繁体   English

高级数据库设计-什么是执行以下任务的最有效方法

[英]Advanced Database Design - Whats the most effective way to execute the following

I am good with ideas, but due to my limited programming experience I sometimes strain to come up with the most effective solution for a given concept. 我的想法很好,但是由于我有限的编程经验,有时我会为特定的概念想出最有效的解决方案。 Currently my mind is trying to fathom the most efficient way to reference a database table specific to a data type. 目前,我的想法是尝试找出引用特定于数据类型的数据库表的最有效方法。

Concept 概念

I am building an admin interface that allows a site owner to 'build' a content set based on selected content 'containers'. 我正在构建一个管理界面,允许站点所有者根据选定的内容“容器”“构建”内容集。 The interface currently holds the various sql data types, such as int, varchar, text, etc. and allows the user to select the data type, label it, and then link them together into a group. 该接口当前包含各种sql数据类型,例如int,varchar,text等,并允许用户选择数据类型,对其进行标记,然后将它们链接在一起成为一个组。

This group is then referenced as an instance of the data set and can be reused. 然后将此组引用为数据集的实例,并且可以重用。 For example, the containers 'title' and 'body' could used to build a simple page and each new instance of this group could be a new page. 例如,容器“ title”和“ body”可用于构建简单页面,并且该组的每个新实例都可以是一个新页面。

Issue 问题

The issue I am having is in referencing these containers in the most efficient manner possible. 我遇到的问题是以尽可能有效的方式引用这些容器。 I can't simply have a table with an instance id and a container id, because there is no way to know they type of container. 我不能简单地拥有一个包含实例ID和容器ID的表,因为无法知道它们的容器类型。 For example, the content-varchar table has an id field and then a value field in the format of varchar. 例如,content-varchar表具有id字段,然后具有varchar格式的值字段。 The content-text table has an id field and then a value field in the format of text. 内容文本表有一个id字段,然后是一个文本格式的value字段。

I thought about making one large table that held each possible type of data, but this would be a gross waste of space. 我曾考虑过要制作一个大表来保存每种可能的数据类型,但这会浪费大量空间。 Currently I use a sub query to select the specific value from the relating table once I know the data type, but there has to be a better solution. 目前,一旦知道数据类型,我就使用子查询从相关表中选择特定值,但是必须有一个更好的解决方案。

What are your ideas / suggestions? 您有什么想法/建议?

You're doing things at a uselessly low level. 您正在做的事情毫无用处。

You're reinventing the relational database the hard way. 您正在艰难地重塑关系数据库。 Inside a relational database. 在关系数据库中。

You can't effectively manage each little piece of data as strongly typed relational data. 您不能有效地将每个小数据作为强类型关系数据进行管理。

One choice is to use higher-level structures (not individual strings, but composite records with multiple things bound together). 一种选择是使用更高级别的结构(不是单个字符串,而是将多个事物绑定在一起的复合记录)。

The other choice is to use just text. 另一种选择是仅使用文本。 It's simpler. 更简单。 Eventually, it all becomes text when the HTML is sent back to the browser. 最终,当HTML发送回浏览器时,它们全部变成了文本。


"...various sql data types, such as int, varchar, text, etc. and allows the user to select the data type, label it, and then link them together into a group." “ ...各种sql数据类型,例如int,varchar,text等,并且允许用户选择数据类型,对其进行标记,然后将它们链接在一起成为一个组。”

Group of simple types == row. 简单类型组==行。 Allowing the user to freely define a table based on a collection of datatypes -- well -- you're making them a programmer. 允许用户根据数据类型的集合自由定义表-很好-您是在使他们成为程序员。 You're creating a front-end for table design. 您正在创建表格设计的前端。

BTW, Lots of tools already do this for you. 顺便说一句,许多工具已经为您做到了。 RoR and Django come to mind: you define a row in a database and a template for positioning those elements on the page and view function that shows how to fetch the row and match it up with a page. RoR和Django浮现在脑海:您在数据库中定义了一行,并在页面上放置了用于定位这些元素的模板,并查看了显示如何获取该行并将其与页面匹配的函数。

Or 要么

Label simple individual text fields with field label and group label. 用字段标签和组标签标记简单的单个文本字段。 Much simpler. 简单得多。 Just text with two keys. 只需两个键即可输入文字。 You can the fetch the "group" and use the label/value pairs to populate the template. 您可以获取“组”,然后使用标签/值对填充模板。 In Django this is one lines of code to fetch rows, turn them into a dictionary and pass it to a template. 在Django中,这是一行代码,用于提取行,将其转换为字典并将其传递给模板。

Here's what the MySQL manual has to say about the TEXT and BLOB fields: 这是MySQL手册中有关TEXT和BLOB字段的内容:

In most respects, you can regard a BLOB column as a VARBINARY column that can be as large as you like. 在大多数方面,您可以将BLOB列视为VARBINARY列,该列可以根据需要任意大。 Similarly, you can regard a TEXT column as a VARCHAR column. 同样,您可以将TEXT列视为VARCHAR列。

Translation: using all TEXT or BLOB columns wouldn't waste space. 翻译:使用所有TEXT或BLOB列都不会浪费空间。 MySQL will truncate what it doesn't use (like in VARCHARs). MySQL将截断它不使用的内容(例如在VARCHAR中)。

Unless I'm missing something, this doesn't sound terribly complicated. 除非我缺少任何东西,否则听起来并不复杂。 But it does sound like you're putting a relational database inside a relational database. 但这听起来确实像是要将关系数据库放入关系数据库中。 That's usually the wrong way to go about things. 这通常是错误的处理方式。

Still, if you insist, there's a few observations to make here: 不过,如果您坚持要说的话,请注意以下几点:

  • A ContentSet defines one or more ContentItems. 一个ContentSet定义一个或多个ContentItems。
  • A ContentItem can be one of several well-defined primitive types, ContentTypes. ContentItem可以是几种定义明确的原始类型之一,ContentTypes。

So, sounds like you'd have four tables: 因此,听起来您将有四个表:

  • content_sets : ContentSets and their associated metadata, such as the user who created each one, the title of the sets, and so on. content_setsContentSets及其关联的元数据,例如创建每个集合的用户,集合的标题等。
  • content_items : ContentItems , along with a foreign key to the ContentSet they belong to. content_itemsContentItems ,以及它们所属的ContentSet的外键。
  • content_types : A list of possible types that can be stored in each ContentItem . content_types :可以存储在每个ContentItem中的可能类型的列表。 Your application will enforce whether the data being stored in each item is correct. 您的应用程序将强制执行每个项目中存储的数据是否正确。
  • content_groups : Instances of ContentSets , containing realized data and a foreign key to the ContentSet they are an instance of. content_groups :的实例ContentSets ,包含实现数据和外键ContentSet他们的一个实例。 Use a property bag/blob/text field to store the data itself. 使用属性包/ blob /文本字段存储数据本身。

Here's one example of this kind of implementation. 这是这种实现的一个例子。 I wouldn't worry too much about subverting the intent of the relational database - as long as you have a good enough reason to. 只要您有足够的理由,我就不必担心颠覆关系数据库的意图。 Anyhow, this implementation went with a single table - and relied on metadata and real-time conversion of data to the needed type. 无论如何,此实现只使用一个表-依赖于元数据和数据实时转换为所需类型。

I had to support a user-extensible set of attributes within the context of a commercial product that users would manage themselves. 我必须在用户可以自行管理的商业产品的上下文中支持一组用户可扩展的属性。 Discarded alternatives included having them pay a DBA to modify their database (too expensive), generating actual tables (too many failure modes), and using a non-relational database (most of the app required a relational database - for reporting, etc). 废弃的替代方案包括让他们付钱给DBA修改数据库(太昂贵),生成实际表(太多失败模式)以及使用非关系数据库(大多数应用程序都需要一个关系数据库-以便进行报告等)。

In this implementation the customer-extensible data was modeled as key-value pairs tied to the extensible tables within the model, in which user-supplied metadata described the keys and their value constraints. 在此实现中,将客户可扩展数据建模为与模型中的可扩展表绑定的键/值对,其中用户提供的元数据描述了键及其值约束。 Both attributes were varchars. 这两个属性都是varchars。 This could hold any kind of data needed at that time (ten years ago): integers, floats, characters, etc. I don't think it could handle binary images, soundfiles, etc. 它可以存储当时(十年前)所需的任何类型的数据:整数,浮点数,字符等。我认为它不能处理二进制图像,声音文件等。

Declarative constraints for type, range, case, unknown value, specific values, etc were handled by a triggered stored procedure that read the user-supplied metadata. 类型,范围,大小写,未知值,特定值等的声明性约束由读取用户提供的元数据的触发存储过程处理。 Conversion to the appropriate type was handled by either the app or a UDF that also read the metadata (can't remember which). 转换为适当类型的操作是由同时读取元数据(不记得是哪个元数据)的应用程序或UDF处理的。

The solution wasn't fast, but it was very flexible, reliable and easy to use. 该解决方案不是很快,但是它非常灵活,可靠并且易于使用。

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

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