奇数据库设计,需要指导

时间:2012-12-22 11:27:17

标签: php mysql database database-design

我可能正在考虑这个错误,但现在就去了。

一台计算机开始在11111111111111111111和99999999999999999999之间吐出数十亿随机数,呈线性排列:

  • 有时,计算机会在行的一端添加一个数字。
  • 有时,计算机会在该行的另一端添加一个数字。
  • 每个号码都有一个或之前会来的号码。
  • 每个号码都有一个后来或将要来的号码。
  • 并非所有数字都是唯一的,许多但不是大多数都会重复。
  • 计算机永远不会停止吐出数字。

当我记录所有这些数字时,我需要能够在任何特定时间做出有根据的猜测:

  • 如果这是我第二次看到一个号码,我必须知道上次排在前面的号码。

  • 如果出现两次以上,我必须知道它前面的数字的概率/频率。

  • 如果这是我第二次看到一个号码,我也必须知道上次排队后的号码。

  • 如果出现两次以上,我必须知道其后的数字的概率/频率。


如何构建MySQL数据库中的表来存储所有这些数字?我使用哪种引擎?为什么?我如何制定我的查询?我需要快速了解,但容量也很重要,因为什么时候会停止吐出它们?

我构思错误的计划:

2表:

1. Unique ID/#
2. #/ID/#

我的想法:

唯一ID几乎总是比数字=更快的匹配更短。 数字重复=更少的ID行=最初匹配更快。

Select * in table2 where id=(select id in table1 where #=?)

OR:

3表:

1. Unique ID/#
2. #/ID
3. ID/#

我的想法:

如果我只需要左/前,或只需要后/右,我会缩小第二个查询的大小。

SELECT # IN table2(or 3) WHERE id=(SELECT id IN table1 WHERE #=?)

OR

1表:

1. #/#/#

思想:

减少查询=减少时间。

SELECT * IN table WHERE col2=#.

我迷路了.... :(每个数字都有四个属性,它们出现在+频率之前,而且出现在+频率之后。

以这种方式思考它会更好吗?如果我在表格中存储并增加频率,我会不再重复,从而加快查询速度?我最初认为如果我存储每一个事件,以编程方式计算频率会更快.......

这样简单的数据,但我只是不知道数据库如何知道哪个更有效。


根据最近的评论,我想补充一些关于实际问题的信息:我有一串无限长的。我试图在这个字符串中存储各种字符或字符块的马尔可夫链频率表。

给定字符串中的任何一点我需要知道下一个状态的概率,以及前一个状态的概率。

我期待用户输入,基于文本语料库和过去的用户输入。与我看到的其他应用程序相比,一个主要的区别是,我在给定时间进一步向下,更多状态,我需要频率数据来提供多种可能性。

我希望能更清楚地了解情况。我不想深入研究这个问题的细节,因为在过去我创造的问题不够具体,无法得到具体的答案。


这似乎好一点。我对这个解决方案的主要问题是:提供“密钥”(状态的前几个字符)是否会提高系统的速度?即查询state_key,然后只查询该查询的结果为完整状态?

Table 1:
name: state
col1:state_id - unique, auto incrementing
col2:state_key - the first X characters of the state
col3:state - fixed length string or state

Table 2:
name: occurence
col1:state_id_left - non unique key from table 1
col2:state_id_right - non unique key from table 1
col3:frequency - int, incremented every time the two states occur next to each other.

QUERY TO FIND PREVIOUS STATES:
SELECT * IN occurence WHERE state_id_right=(SELECT state_id IN state WHERE state_key=? AND state=?)

QUERY TO FIND NEXT STATES:
SELECT * IN occurence WHERE state_id_left=(SELECT state_id IN state WHERE state_key=? AND state=?)

2 个答案:

答案 0 :(得分:2)

我不熟悉马尔可夫链,但这是试图回答这个问题。注意:为简化起见,我们将每个数字字符串称为“状态”。

首先,我想象一个像这样的表

Table states:
order : integer autonumeric (add an index here)
state_id : integer (add an index here)
state : varchar (?)

顺序:只需使用序号(1,2,3,...,n),这样可以轻松搜索上一个或下一个状态。

state_id:与州相关联的唯一编号。例如,您可以使用数字1来表示状态'1111111111 ... 1'(无论序列的长度是多少)。重要的是,状态的重新发生需要使用之前使用的相同state_id。您可以根据字符串(可能减去一个数字)来表示state_id。当然,只有当可能状态的数量适合MySQL int字段时,state_id才有意义。

状态:这是数​​字的字符串'11111111 ... 1'到'99999999 ... 9'...我猜这只能存储为字符串但是如果它适合整数/数字您应该尝试它,因为它可能不需要state_id

state_id的重点在于搜索数字比搜索文本更快,但在性能方面总是需要权衡......配置文件并找出瓶颈以做出更好的设计决策。

那么,你如何寻找先前出现的状态S_i?

“SELECT order,state_id,state FROM states WHERE state_id =”然后附加get_state_id(S_i),其中get_state_id理想地使用公式为状态生成唯一ID。

现在,使用order-1或order + 1,您可以访问发出附加查询的邻近州。

接下来,我们需要跟踪不同事件的发生频率。您可以在不同的表中执行此操作,如下所示:

Table state_frequencies:
state_id integer (indexed)
occurrences integer

只有在获得数字时才添加记录。

最后,您可以使用表来跟踪邻近状态的频率:

Table prev_state_frequencies (next_state_frequencies is the same):
state_id: integer (indexed)
prev_state_id: integer (indexed)
occurrences: integer

通过查看状态(在state_frequencies中)的出现次数与其前任状态(在prev_state_frequencies中)的出现次数,您将能够推断概率(我猜这是您要做的事情)。

我不确定我的问题是否正确,但如果这是有道理的,我猜我有。

希望它有所帮助, AH

答案 1 :(得分:1)

在我看来,马尔可夫链是有限的,所以首先我要从定义链的极限开始(即26个字符用x个空格来填充),然后你可以计算出可能的组合总数。如果我没记错的话,确定某个字符排列的概率:


 x =((C)(C))(P)
哪里
C =可能的字符数和
P =总潜在结果。

这是一大堆数据,用于存储和创建过滤数据的过程可能会成为一项看似无穷无尽的任务。

- > 如果你在表中使用自动递增的id,你可以查询表并使用preg_match来测试前面结果的新结果然后将总结果数与新结果一起插入表中,这也可以让你查询前面的结果可以看到之前的结果,这应该可以让您对结果中的模式有一个大概的了解,以及统计相关性和新算法生成的一般基础