我目前正在开发一个涉及在HTML5 SQL-Lite数据库中存储数据的项目。目前,我有一个如下的架构(4个表):
TransData:
-----------------------------------------------------------
| TID | UserName | TransColor | ... | Date | Note |
-----------------------------------------------------------
| 6 | Brendan | Red | ... | | |
-----------------------------------------------------------
| 7 | Brendan | Red | ... | | 1 |
-----------------------------------------------------------
FullData:
-----------------------------------------------------------
| TID | UserName | TransColor | ... | Date | Note |
-----------------------------------------------------------
| 1 | Brendan | Red | ... | | Start |
-----------------------------------------------------------
| ... | Brendan | Red | ... | | |
-----------------------------------------------------------
| 40 | Brendan | Red | ... | | End |
-----------------------------------------------------------
SalamanderData:
----------------------------------------------------
| SID | SalamanderName | Length | ... | TID |
----------------------------------------------------
| 1 | Northern-Slimy | 16 | ... | 6 |
----------------------------------------------------
| 2 | Two-Lined | 26 | ... | 6 |
----------------------------------------------------
| 3 | Two-Lined | 12 | ... | 7 |
----------------------------------------------------
SalamanderData:
----------------------------------------------------
| SID | SalamanderName | Length | ... | TID |
----------------------------------------------------
| 1 | Northern-Slimy | 16 | ... | 6 |
----------------------------------------------------
| 2 | Two-Lined | 26 | ... | 6 |
----------------------------------------------------
| 3 | Two-Lined | 12 | ... | 7 |
----------------------------------------------------
注意:TransData中的“Note”列用于指向FullData字段中集合的起始数据点。
我的应用程序和服务器之间的数据库不应该是同步的。我只是试图将所有这些表转储到服务器上的数据库中(通过转储我的意思是,更新对其他表的引用,然后插入到服务器数据库中)。
我打算使用MAX(TID-Server) + TID-App = new TID-Server
,并将更新级联到表格中。
你会怎么做呢?
答案 0 :(得分:6)
从Dan Pichelman的评论中,问题是客户端将记录插入本地数据库,为此,必须确定它们的主键。但是,鉴于所有不同的客户端都在做同样的事情,新的PK会在它们到达服务器时发生冲突。
这是一个常见问题,是物理上断开连接的系统(至少有时是这种情况),或者在没有单点故障的系统中,例如在共享序列发生器中。
一些常见的解决方案是:
<强> GUID 强>
这里PK是128位(或更大)的随机数。任何两个PK相同的可能性非常小。但是为了进一步减少碰撞的变化,GUID算法包括使用唯一的机器标识符(网络MAC)和时间进行播种。在同一台机器上生成的两个GUID永远不会发生冲突,并且在具有不同MAC的机器上也不会生成GUID。大多数机器和语言都具有生成GUID的本机函数,但JavaScript没有。参见:
分区命名方案
在这个方案中,PK又是一个很大的数字(真的是位域),你将它划分为分层方式。一个很好的例子是国际电话系统(至少在便携式号码之前)。这里的电话号码分为:
在您的情况下,您可以按以下方式对数字进行分区:
将这三者结合起来,您将拥有一个保证独特的PK。
PK'许可'服务器
前两个建议的优点是它们完全断开连接。如果您有一个已连接的客户端,则可以拥有一个在客户端请求时提供PK的Web服务。
为了提高效率,它可能会返回一批100个数字。甚至可以在用户登录时返回。
客户可以全部使用它们并请求更多。可能存在客户端忘记状态并在全局PK序列中留下“漏洞”的情况。这几乎肯定不是一个问题。
一些注意事项
有时您可能会喜欢顺序PK以用于表格排序。在这种情况下,您需要按客户或创建时间订购吗?如果其中一个很重要,您可以将分区命名方案评级更高。根据需要将客户端或时间作为第一个分区。或者,在表格中添加更多列。
如果您不想要分区命名方案的固定结构,GUID将运行良好。
如果您想要集中协调,请使用PK许可证服务器。
答案 1 :(得分:0)
我不知道这样做的美学方法,但我通过编写存储过程来“解决”它:
第一个表格很简单 - 根据需要更新或插入。如果执行插入操作,则获取新插入记录的主键,然后相应地处理相关表(这通常意味着使用新主键插入数据)。在您完成关系时,根据需要重复。对于4张桌子你应该没问题,但是我讨厌40岁。
在我的情况下,它很乱,并且涉及临时查找表,其中包含oldPK和newPK。
这也是一个相当冗长的&amp;繁琐的代码,其唯一的兑换功能就是它的工作原理。
答案 2 :(得分:0)
这与你要求的内容有些不同,所以如果这完全不合适,请评论我将删除它。但是你没有说明为什么服务器/客户端无法与主键同步的任何特定原因(在我看来这是真正的问题)。
我也在假设(根据您的数据和您的问题)我们正在讨论一个带有用户创建内容(如日志)的webapp,偶尔会上传到服务器。
因此,对于体育运动,您是否考虑过使用由多个领域构建的主键?这样,您可以在本地数据库中进行自动增量,将数据转储到服务器,并且不会与其他用户数据冲突。 SalamanderData表的一个例子是:
CREATE TABLE SalamanderData
(
SID int NOT NULL,
SalamanderName varchar(255),
Length int,
... ...,
TID int NOT NULL,
CONSTRAINT pk_SDataEntry PRIMARY KEY (SID,TID)
)
然后会从SID和TID中创建一个PK。
阅读我的帖子并查看其他答案,我意识到这就是安德鲁所建议的,所以即使这对你有所帮助,你也应该接受他的回答
保留答案,以便澄清解决方案并提供代码示例