如何防止MariaDB中导入的表中的重复ID?

时间:2018-01-24 07:16:02

标签: database codeigniter duplicates mariadb auto-increment

(在那之前,我为我糟糕的英语道歉) 我有这样的研究案例:

我目前在使用Web应用程序时出现问题。我为某个公司制作了一个Web应用程序。我使用CodeIgniter 3制作了应用程序。

我使用Maria DB构建了数据库。对于每个表中的id,我使用 Auto-increment id 作为每个表的应用程序数据库。我通常将Web应用程序部署到云服务器(有时公司有自己的专用服务器,但有时却没有)。有一天,有一家公司,他们不想将我之前制作的应用程序部署到云端(出于安全目的,他们说)。

该公司希望将该应用程序部署到员工的个人电脑上,而每个员工的电脑不相互连接(即独立的个人电脑/个人电脑/员工的笔记本电脑)。他们说,他们会每5个月将员工个人电脑的所有数据收集到公司的数据中心,当然数据中心也没有连接到互联网。我告诉他们这不是存储数据的好方法。 (因为当我尝试将所有数据合并为一个数据时,数据将会重复,因为我的每个表的列ID都在自动增量ID 中,并且它是主键< /强>)。不幸的是,公司仍然希望以这种方式保留应用程序,我不知道如何解决这个问题。

他们至少有10名员工会使用此网络应用。据此,我必须亲自将应用程序部署到10台PC上。

其他信息:每位员工都有自己从公司获得的唯一身份证,我为每位员工制作了 auto_increment id ,如下表所示:

id   |  employee_id  | employee_name   |
1    | 156901010     |  emp1
2    | 156901039     |  emp2
3    | 156901019     |  emp3
4    | 156901015     |  emp4
5    | 156901009     |  emp5
6    | 156901038     |  emp6

问题是每当他们从该应用程序填充表单时,某些表不存储员工的id,而是存储来自增量id的新id。

例如 electronic_parts 表。它们具有如下属性:

| id  |  electronic_part_name  |  kind_of_electronic_part_id  |

如果emp1填写了网络应用中的表单,则表格的内容如下所示。

| id  |  electronic_part_name  |  kind_of_electronic_part_id  |
|  1  |   switch               |           1               |

如果emp2填写了网络应用中的表单,则表格的内容如下所示。

| id  |  electronic_part_name  |  kind_of_electronic_part_id  |
|  1  |      duct tape         |           10              |

当我试图将表的内容合并到数据中心时,它会因为重复的ID而崩溃。

当我在其他表中考虑我的外键时,情况变得更糟......例如customer_order表。

customer_order列的表格如下所示(只是一个示例,不是实际的表格,但类似)。

|id  |  customer_name   |  electronic_parts_id  |  cashier(a.k.a employee_id, the increment id one, not the id that employee got from a company as i described above )  |
| 1  |   Henry          |           1           |              10              |
| 2  |   Julie          |           2           |              9               |

有谁知道如何解决这个问题?或者有人可以建议/推荐一些解决这个问题的好方法吗?

注意:每个员工都有自己的应用程序数据库,因此数据库不是集中式的,它是一个独立的数据库,这意味着,我必须逐个将数据库安装到员工的PC上

5 个答案:

答案 0 :(得分:9)

这是一个非传统的情况,你可以有一个非传统的解决方案。

我可以建议你解决这个问题的两种方法。

  1. 不使用自动增量主键生成UUID而是将其用作主键。关于重复的可能性 在随机UUID中:仅在每秒生成10亿UUID之后 未来100年

    在CodeIgniter中,您可以使用以下代码段执行此操作。

    $this->db->set('id', 'UUID', FALSE);
    

    这将生成一个36个字符的十六进制密钥(带有4个破折号) 包括在内)。

    ac689561-f7c9-4f7e-be94-33c6c0fb0672
    

    正如您所看到的,它使用CodeIgniter DB在字符串中有破折号 函数将使用破折号将其插入数据库中,它仍然是 将工作。如果它看起来不干净,你可以删除和 将字符串转换为32-char键。

    您可以在[CodeIgniter]的帮助下使用以下功能 UUID图书馆] [1]。

    function uuid_key {
            $this->load->library('uuid');
            //Output a v4 UUID 
            $id = $this->uuid->v4();
            $id = str_replace('-', '', $id);
            $this->db->set('id', $id, FALSE);
    }
    

    现在我们有一个32字节的密钥,

    ac689561f7c94f7ebe9433c6c0fb0672
    
  2. 另一种解决这种情况的非常规方法是 添加函数以记录所有已处理的Insert,Update,Delete查询 在站点中本地文件。通过这种方式,在每个地方 实现将生成一个具有实际列表的日志文件 以正确的顺序顺序修改数据库的查询。

    在任何时候,数据库的状态都是结果 所有这些查询的集合,直到该日期为止。

    因此,当您准备好从中收集数据时,每5个月 员工个人电脑,而不是采取数据转储,采取这个 带有所有查询日志的文件。(注意:这样的查询日志不会有 自动递增ID,因为它只会在实时创建时生成 它是针对数据库执行的。 )

    使用此类文件将数据导入数据中心。这不会 冲突因为它会在您的数据中心中生成自动增量 即时的。 (希望您不必将本地链接到数据中心 在未来的任何时间点)

    [1]:https://github.com/Repox/codeigniter-uuid

答案 1 :(得分:4)

是否在其他任何表中使用id?它可能会涉及JOIN。如果是这样,你就会解决这个问题。

如果id未在其他任何地方使用,则值无关紧要,行可以重新编号。这可以通过将各种来源的数据加载到同一个表中来完成(粗略地说),但在加载中包含id

或者,如果存在UNIQUE的其他列(或列组合),则将 <{em> PRIMARY KEY并删除id

哪种情况适用?我们可以更详细地追求。请为SHOW CREATE TABLE提供相关的任何表格。

在我的第一种情况下(其中id在其他地方用作FK),请执行以下操作:

使用id将行插入表中时,请将值递增足以避免与现有ID冲突。然后做(在同一交易中):

UPDATE the_other_table SET fk_id = fk_id + same_increment.

根据需要对每个其他表和每个id重复一次。

答案 2 :(得分:2)

我认为您的问题来自您的数据库 ...您没有很好地设计它。 如果你有两个差异用户的ID,那么它就是错误

如果您在数据库中创建了自己的ID字段唯一,那么两位员工就不会拥有相同的ID,因此您的问题出在您的表格设计中。

只需启动您的ID字段,您的问题就会得到解决。

    CREATE TABLE [YOUR TABLE NAME](
        [ID]  int   NOT NULL    IDENTITY(1,1)   PRIMARY KEY,
....

答案 3 :(得分:0)

id是否需要是整数?如果不是,你可以在id上使用前缀,这样每个员工的输入一般都是唯一的。这意味着你必须放弃自动增量并只计算表格数据(假设你没有删除任何记录。)

答案 4 :(得分:0)

你可能需要用PHP编写一个代码来处理这个问题。如果其他表已经基于唯一/主键,那么它就好了。

您也可以在导入后执行此操作。 像这样 Find duplicates in the same table in MySQL