简体   繁体   English

在MySQL的同一数据库中复制表的一部分

[英]Replicate part of a table in the same database in MySQL

I have a large table (several million rows) in a MySQL (version 5.0) database that has data inserted into it at a very frequent rate. 我在MySQL(5.0版)数据库中有一个大表(几百万行),该表中的数据插入频率很高。

There are also less frequent select statements done against the database that only required the latest data (ie the newest 10000 rows), is there a way to create a table that would keep a copy of data from the main table and would dynamically add new rows whenever a new row was added to the main table (I can delete the old data periodically so that's not too much of an issue) without causing much of an impact to the main table. 还有一些针对数据库执行的仅需要最新数据(即最新的10000行)的select语句,频率较低,有没有办法创建一个表,该表将保留主表中的数据副本并动态添加新行每当在主表中添加新行时(我可以定期删除旧数据,这样就不会有太大问题),而不会对主表造成太大影响。

If possible I would also like to Index rows in the 2nd table slightly differently. 如果可能的话,我还希望索引第二张表中的行略有不同。

It sounds like you should use triggers . 听起来您应该使用触发器

You'll need three triggers on the large table: 大表上需要三个触发器:

  • AFTER INSERT, for each row you'll need to copy the new row into the smaller table and delete the oldest row from the smaller table 插入后,对于每一行,您需要将新行复制到较小的表中,并从较小的表中删除最旧的行
  • AFTER UPDATE, for each row you'll need to check whether that row is in the smaller table and if it is, make the same updates to it 更新后,对于每一行,您需要检查该行是否在较小的表中,如果存在,则对其进行相同的更新
  • AFTER DELETE, for each row you'll need to check whether that row is in the smaller table and if it is, remove it. 删除后,对于每一行,您需要检查该行是否在较小的表中,如果存在,则将其删除。

For example: 例如:

DELIMITER //
CREATE TRIGGER after_insert AFTER INSERT ON big_table
FOR EACH ROW
BEGIN
    DECLARE small_table_rows INTEGER;
    INSERT INTO small_table (field1, field2) VALUES (NEW.field1, NEW.field2);
    SELECT COUNT(*) INTO small_table_rows FROM small_table;
    IF small_table_rows > 10000 THEN
        DELETE FROM small_table ORDER BY id ASC LIMIT 1;
    END IF
END;//
DELIMITER ;

DELIMITER //
CREATE TRIGGER after_update AFTER UPDATE ON big_table
FOR EACH ROW
BEGIN
    UPDATE small_table
    SET field1 = NEW.field1, field2 = NEW.field2
    WHERE small_table.id = NEW.id;
END;//
DELIMITER ;

DELIMITER //
CREATE TRIGGER after_delete AFTER DELETE ON big_table
FOR EACH ROW
BEGIN
    DELETE FROM small_table WHERE small_table.id = OLD.id;
END;//
DELIMITER ;

It's fairly straightforward, though the triggers can get unwieldy if the tables have a lot of columns. 这很简单,但是如果表中有很多列,触发器可能会变得笨拙。 You may want to consider the performance characteristics of MyISAM vs InnoDB; 您可能要考虑MyISAM与InnoDB的性能特征; InnoDB may offer better overall performance depending on what sorts of queries you are running. InnoDB可能会提供更好的整体性能,具体取决于您运行的查询类型。

You don't want to use views; 您不想使用视图; views in MySQL are not materialized, so you won't generally get any performance benefit (which is what it sounds like you want) and you won't be able to index the view differently from the table(s) on which the view is based. MySQL中的视图尚未实现,因此通常不会获得任何性能上的好处(这听起来就是您想要的),并且无法将视图的索引与视图所在的表的索引不同基于。

您可以使用将在父级更新的情况下更新的VIEWS ,也可以使用TRIGGERS

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

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