1

我为我的数据库设计付出了很多努力,但我想我现在意识到我犯了一个重大错误。

背景:(如果您不需要背景,请跳至“问题”。)

数据库支持网站模板的自定义 CMS 层。该模板的用户仅限于打开和关闭页面,但不能创建自己的“新”页面。此外,许多元素是不可编辑的。

因此,如果一个页面有一段我希望他们能够编辑的文本,我会“手动”为其分配一个静态 ID:

<h2><%= CMS.getDataItemByID(123456) %></h2>

注意:脚本语言与此问题无关,但设计强制每个表具有唯一的列名。因此,主键等的“TableNameSingular_id”约定。

脚本语言将对这些表进行查找以找到字符串。

mysql> SELECT * FROM CMSData WHERE CMSData_data_id = 123456;
+------------+-----------------+-----------------------------+
| CMSData_id | CMSData_data_id | CMSData_CMSDataType_type_id |
+------------+-----------------+-----------------------------+
|          1 |          123456 |                           1 |
+------------+-----------------+-----------------------------+

mysql> SELECT * FROM CMSDataTypes WHERE CMSDataType_type_id = 1;
+----------------+---------------------+-----------------------+------------------------+
| CMSDataType_id | CMSDataType_type_id | CMSDataType_type_name | CMSDataType_table_name |
+----------------+---------------------+-----------------------+------------------------+
|              1 |                   1 | String                | CMSStrings             |
+----------------+---------------------+-----------------------+------------------------+

mysql> SELECT * FROM CMSStrings WHERE CMSString_CMSData_data_id=123456;
+--------------+---------------------------+----------------------------------+
| CMSString_id | CMSString_CMSData_data_id | CMSString_string                 |
+--------------+--------------------------------------------------------------+
|            1 |                    123456 | The answer to the universe is 42.|
+--------------+---------------------------+----------------------------------+

呈现的文本将是:

<h2>The answer to the universe is 42.</h2>

这适用于“静态”元素,例如上面的示例。我对其他数据类型使用完全相同的方法,例如文件规范、电子邮件地址、日期等。

但是,当我想允许用户动态生成内容时它失败了。

例如,有一个“事件”页面,它们将由用户通过单击“添加事件”或“删除事件”动态创建。

事件表将使用键来引用具有以下数据项的其他表:

Data Item:  Table:
--------------------------------------------------
Date        CMSDates
Title       CMSStrings (As show above)
Description CMSTexts   (MySQL TEXT data type.)
--------------------------------------------------

问题:

这意味着,每次创建事件时,我都需要在 CMSData 表中创建以下行;

+------------+-----------------+-----------------------------+
| CMSData_id | CMSData_data_id | CMSData_CMSDataType_type_id |
+------------+-----------------+-----------------------------+
|          x |               y |                           6 | (Event)
|        x+1 |             y+1 |                           5 | (Date)
|        x+2 |             y+2 |                           1 | (Title)
|        x+3 |             y+3 |                           3 | (Description)
+------------+-----------------+-----------------------------+

但是,有问题。在 MySQL 中,您只能有 1 个 AUTO INCREMENT 字段。

如果我查询 CMSData_data_id 的最大值并将其加 1,则有可能存在竞争条件,并且其他人首先抓住了它。

这个问题通常是如何解决的——或者首先是如何避免的?

谢谢,

埃里克

4

2 回答 2

1

id 应该是无意义的,除非是唯一的。无论 4 个 id 的块是否连续,您的设计都应该有效。

重新设计您的实现以单独添加部分,而不是作为一个 4 块。这样做应该可以简化整体,并提高您的可伸缩性。

于 2013-09-03T16:32:41.227 回答
0

在写入之前锁定表格怎么样?这样,当您在 CMSData 表中插入一行时,您可以获得最后一个 id。

其他建议是不要有一个递增的 id,而是一个唯一的生成的,比如一个 guid 左右。

锁定表

于 2013-09-01T15:25:23.920 回答