简体   繁体   English

同步2个表:一个带引擎=内存另一个带引擎= InnoDB

[英]Sync 2 tables: one with engine = Memory another with engine = InnoDB

I have 2 tables, student_memory (engine = Memory) and student_innodb (engine = InnoDB). 我有2个表,student_memory(engine = Memory)和student_innodb(engine = InnoDB)。 student_memory is being updated continuously (at an interval of 2 seconds) by some thread. 某个线程正在不断更新student_memory(间隔为2秒)。 I have to sync both the tables (say at an interval of 10 seconds). 我必须同步两个表(比如每隔10秒)。 I have some methods for that: 我有一些方法:
1. Create insert/update/delete statements by seeing the difference between the 2 tables and run those query on student_innodb. 1.通过查看2个表之间的差异并在student_innodb上运行这些查询来创建插入/更新/删除语句。
2. Drop student_innodb , ALTER TABLE student_memory ENGINE = INNODB, RENAME TO student_innodb ; 2.删除student_innodb ,ALTER TABLE student_memory ENGINE = INNODB,RENAME TO student_innodb ;
3. Truncate student_innodb table and do, insert into student_innodb select * from student_memory ; 3.截断student_innodb表,然后插入student_innodbstudent_memory选择*;

I'm using 2nd approach as this is saving me from comparing rows of the tables, creating INSERT/UPDATE/DELETE and executing them. 我正在使用第二种方法,因为这可以节省我比较表的行,创建INSERT/UPDATE/DELETE并执行它们。 But I'm not sure about the performance. 但我不确定性能。 There can be around 1000-100000 Rows in these tables. 这些表中可以有大约1000-100000行。 Can anyone suggest any other better solution or which one should I use? 谁能建议任何其他更好的解决方案或我应该使用哪一个?

To answer your question, possibly the fastest way to do this is to have some sort of primary key on both tables (eg student_id). 要回答你的问题,可能最快的方法是在两个表上都有某种主键(例如student_id)。 You should then add a third memory table changed_students_memory that has only a student_id field as it's primary key. 然后,您应该添加第三个内存表changed_students_memory,它只有一个student_id字段作为它的主键。

Every time you make a change to students_table, you should: 每当你改变students_table时,你应该:

INSERT (student_id) VALUES (:student_id) INTO changed_students_memory ON DUPLICATE KEY IGNORE

Then you have just a list of records to update in changed_students_memory. 然后,您只需要在changed_students_memory中更新要更新的记录列表。 You can then update your innodb table as such: 然后,您可以更新您的innodb表:

BEGIN;

UPDATE
  student_innodb AS i
  JOIN student_memory AS m USING (student_id)
  JOIN changed_students_memory USING (student_id)
SET
  i.<fieldname1> = m.<fieldname1>,
  i.<fieldname2> = m.<fieldname2>... ;

TRUNCATE TABLE changed_students_memory;

COMMIT;

This will be much faster if you're only updating a small percentage of the rows. 如果您只更新一小部分行,这将会快得多。 I'd also mention that under that assumption using the third table is preferable to adding a "dirty" column to the exiting memory table and adding an index on it, since most times the optimizer won't use the index since it won't think it's selective enough. 我还要提到的是,根据该假设,使用第三个表比将“脏”列添加到现有内存表并在其上添加索引更好,因为大多数情况下优化器不会使用索引,因为它不会认为它有足够的选择性。

Having said all of that - I'm guessing that if you're doing all this craziness with an in-memory table, you're approaching your problem wrong. 说完了所有这些 - 我猜测如果你在内存表中做了所有这些疯狂的事情,那么你的问题就会接近你的错误。 In-memory tables are not meant to store data for long periods of time. 内存表并不意味着长时间存储数据。 If the database goes down, you will lose your data. 如果数据库出现故障,您将丢失数据。 If you have in-memory table as a performance optimization, you're better off tweaking your INNODB setup instead. 如果你有内存表作为性能优化,你最好调整你的INNODB设置。 INNODB is very fast if configured correctly. 如果配置正确,INNODB非常快。 I have it easily handling load from hundreds of concurrent connections. 我可以轻松处理来自数百个并发连接的负载。 INNODB will keep all hot data in memory if you give it enough memory (see innodb_buffer_pool_size in my.cfg/my.ini). 如果给它足够的内存,INNODB会将所有热数据保存在内存中(请参阅my.cfg / my.ini中的innodb_buffer_pool_size)。

I know that this is an old question, but for people that come from search engines (like myself) I should say: 我知道这是一个老问题,但对于那些来自搜索引擎的人(比如我自己),我应该说:

NEVER implement any of solutions in above question, by first one you could get partially data lost and by two other solutions, you could get full data lost! 永远不要在上面的问题中实现任何解决方案,首先你可以获得部分数据丢失,而另外两个解决方案,你可能会丢失全部数据!

The best way is INSERT/UPDATE/DELETE data on innodb(or memory), and set AFTER INSERT/AFTER UPDATE/AFTER DELETE triggers to update memory the other table. 最好的方法是对innodb(或内存)执行INSERT / UPDATE / DELETE数据,并设置AFTER INSERT / AFTER UPDATE / AFTER DELETE触发器来更新另一个表的内存。 So, you never lose data, but don't forget to enable Transaction for INSERT/UPDATE/DELETE! 所以,你永远不会丢失数据,但不要忘记为INSERT / UPDATE / DELETE启用Transaction!

This way, you never get data loss, and it is very fast to read data from memory table. 这样,您永远不会丢失数据,并且从内存表中读取数据的速度非常快。 And Memory table will always get synced to Innodb one automatically. 内存表将始终自动同步到Innodb。

1 Last thing: don't forget to config mysql to automatically sync this two tables at server start! 1最后一件事:不要忘记配置mysql在服务器启动时自动同步这两个表!

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

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