选用redis协理mysql数据库搬迁,redismysql

来源:http://www.sh-fengwen.com 作者:家常菜谱 人气:113 发布时间:2019-09-03
摘要:利用redis协助mysql数据库搬迁,redismysql 最近公司新项目上线,需要数据库搬迁,但新版本和老版本数据库差距比较大,关系也比较复杂。如果用传统办法,需要撰写很多mysql脚本,工程

利用redis协助mysql数据库搬迁,redismysql

  最近公司新项目上线,需要数据库搬迁,但新版本和老版本数据库差距比较大,关系也比较复杂。如果用传统办法,需要撰写很多mysql脚本,工程量虽然不大,但对于没有dba的公司来说,稍微有点难度。本人就勉为其难,用redis作为mysql中转站,先把原来的mysql数据转移到redis里面,再从redis转换到新的mysql。整个过程脉络清晰,脚本简单。

  首先,公司之前的项目是,flask+sqlalchemy的方式,直接复制原来的model文件,稍微修改一下,就有以下代码。

  1 # coding:utf-8
  2 from sqlalchemy import create_engine, ForeignKey, Column, Integer, String, Text, DateTime, Boolean, and_, or_,
  3     SmallInteger, func, Numeric, select, Float, Table, TIMESTAMP, DECIMAL, desc
  4 from sqlalchemy.orm import relationship, backref, sessionmaker, scoped_session
  5 from sqlalchemy.ext.declarative import declarative_base
  6 from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method, Comparator
  7 from sqlalchemy import event
  8 import redis
  9 import json
 10 
 11 mysql_info = "mysql://username:[email protected]_address:3306/databasename?charset=utf8"
 12 redis_store = redis.Redis(host='127.0.0.1', port=6380, password='password', db=5)
 13 
 14 engine = create_engine(mysql_info, pool_recycle=7200)
 15 Base = declarative_base()
 16 
 17 
 18 class User(Base):
 19     __tablename__ = 'user'
 20 
 21     id = Column('id', Integer, primary_key=True)
 22     phone_number = Column('phone_number', String(11), index=True)
 23     password = Column('password', String(30))
 24     nickname = Column('nickname', String(30), index=True, nullable=True)
 25     headpic = Column('headpic', String(100), nullable=True)
 26     register_time = Column('register_time', DateTime, index=True)
 27     email = Column('email', String(50), default='', index=True)
 28     real_name = Column('real_name', String(50), default='', index=True)
 29     user_admin = Column('user_admin', Integer, index=True, default=0)
 30     rc_token = Column('rc_token', String(100))
 31     device_token = Column('device_token', String(100), unique=True, nullable=True)
 32     unit_id = Column('unit_id', Integer, ForeignKey('unit.id'))
 33     unit = relationship("Unit", backref=backref('users'))
 34 
 35     def to_dict(self):
 36         return dict(id=self.id, phone_number=self.phone_number,
 37                     password=self.password, nickname=self.nickname,
 38                     headpic=self.headpic, register_time=self.register_time.strftime('%Y-%m-%d %H:%M:%S'),
 39                     user_admin=self.user_admin, rc_token=self.rc_token,
 40                     unit_id=self.unit_id, device_token=self.device_token,
 41                     )
 42 
 43 
 44 class Group(Base):
 45     __tablename__ = 'groups'
 46 
 47     id = Column('id', Integer, primary_key=True)
 48     name = Column('name', String(100), index=True)
 49     address = Column('address', String(100), index=True, nullable=True)
 50     contact_person = Column('contactperson', String(30), nullable=True)
 51     contact_number = Column('contactnumber', String(30), nullable=True)
 52     unit_id = Column('unit_id', Integer, ForeignKey('unit.id'))
 53     unit = relationship('Unit', backref=backref('groups'))
 54 
 55 
 56 class Monitor(Base):
 57     __tablename__ = 'monitor'
 58 
 59     id = Column('id', Integer, primary_key=True)
 60     u_id = Column('sn_num', String(10), index=True)
 61     phone_num = Column('phone_num', String(20), index=True, nullable=True)
 62     name = Column('name', String(40), index=True, nullable=True)
 63     position = Column('position', String(40), nullable=True)
 64     join_time = Column('join_time', DateTime, index=True, nullable=True)
 65     group_id = Column('group_id', Integer, ForeignKey('groups.id'))
 66     group = relationship("Group", backref=backref('monitors'))
 67     longitude = Column('longitude', DECIMAL(12, 9), default=31.000000)
 68     latitude = Column('latitude', DECIMAL(12, 9), default=121.000000)
 69 
 70     def to_dict(self):
 71         unit_id = self.group.unit_id
 72         return dict(id=self.id, u_id=self.u_id, phone_num=self.phone_num, name=self.name,
 73                     position=self.position, join_time=self.join_time.strftime('%Y-%m-%d %H:%M:%S'), unit_id=unit_id,
 74                     longitude=str(self.longitude), latitude=str(self.latitude))
 75 
 76 
 77 class Unit(Base):
 78     __tablename__ = 'unit'
 79 
 80     id = Column('id', Integer, primary_key=True)
 81     name = Column('name', String(100), index=True, nullable=True)
 82     address = Column('address', String(100), index=True, nullable=True)
 83     contact_person = Column('contactperson', String(30), index=True, nullable=True)
 84     contact_number = Column('contactnumber', String(30), nullable=True)
 85     device_operation_password = Column('device_operation_password', String(4), nullable=True)
 86     rc_group_id = Column('rc_group_id', String(50), index=True, nullable=True)
 87     rc_group_name = Column('rc_group_name', String(50), index=True, nullable=True)
 88     longitude = Column('longitude', DECIMAL(12, 9), nullable=True)
 89     latitude = Column('latitude', DECIMAL(12, 9), nullable=True)
 90     active = Column('active', SmallInteger, index=True, default=0)
 91 
 92     def to_dict(self):
 93         return dict(id=self.id, name=self.name, address=self.address,
 94                     contact_person=self.contact_person, contact_number=self.contact_number,
 95                     device_operation_password=self.device_operation_password,
 96                     rc_group_id=self.rc_group_id, rc_group_name=self.rc_group_name,
 97                     longitude=str(self.longitude), latitude=str(self.latitude), active=self.active)
 98 
 99 db_session = scoped_session(sessionmaker(autocommit=False,
100                                          autoflush=False,
101                                          bind=engine))
102 
103 Base.query = db_session.query_property()
104 
105 
106 def old_sql_2_redis():
107     redis_store.flushdb()
108     units = Unit.query.all()
109     [redis_store.rpush('units', json.dumps(unit.to_dict())) for unit in units]
110 
111     users = User.query.all()
112     [redis_store.rpush('users', json.dumps(user.to_dict())) for user in users]
113 
114     monitors = Monitor.query.all()
115     [redis_store.rpush('monitors', json.dumps(monitor.to_dict())) for monitor in monitors]
116 
117 if __name__ == '__main__':
118     old_sql_2_redis()

把原来的数据库复制到本地redis了,看查看里面的元素。比如user数据,直接建一个user的list,每个appened其json格式的数据就可以了。主要注意点就是,如果新版本的表中没有的字段,就不要写入的redis了。

 

第二步就是把本地redis里面的数据,放到新的数据库上。这边要注意以下,把需要修改的地方要标示出来,可能加了其他字段,这些字段没有默认值的话,要自己添加上。过程也比较简单。

  1 # coding:utf-8
  2 from sqlalchemy import create_engine, ForeignKey, Column, Integer, String, Text, DateTime, Boolean, and_, or_,
  3     SmallInteger, func, Numeric, select, Float, Table, TIMESTAMP, DECIMAL, desc
  4 from sqlalchemy.orm import relationship, backref, sessionmaker, scoped_session
  5 from sqlalchemy.ext.declarative import declarative_base
  6 from sqlalchemy.ext.hybrid import hybrid_property, hybrid_method, Comparator
  7 from sqlalchemy import event
  8 import redis
  9 import json
 10 import datetime
 11 import uuid
 12 
 13 mysql_info = "mysql://username:[email protected]_address:3306/database_name?charset=utf8"
 14 redis_store = redis.Redis(host='127.0.0.1', port=6380, password='password', db=5)
 15 
 16 engine = create_engine(mysql_info, pool_recycle=7200)
 17 Base = declarative_base()
 18 
 19 
 20 class User(Base):
 21     __tablename__ = 'user'
 22 
 23     id = Column('id', Integer, primary_key=True)
 24     phone_number = Column('phone_number', String(11), index=True)
 25     password = Column('password', String(30))
 26     nickname = Column('nickname', String(30), index=True, nullable=True)
 27     headpic = Column('headpic', String(100), nullable=True)
 28     register_time = Column('register_time', DateTime, index=True, default=datetime.datetime.now)
 29     user_admin = Column('user_admin', SmallInteger, index=True, default=0)
 30     hidden_user = Column('hidden_user', SmallInteger, index=True, default=0)
 31     rc_token = Column('rc_token', String(100), nullable=True)
 32     device_token = Column('device_token', String(100), unique=True, nullable=True)
 33     unit_id = Column('unit_id', Integer, ForeignKey('unit.id'))
 34     unit = relationship('Unit', backref=backref('users'))
 35 
 36 
 37 class Monitor(Base):
 38     __tablename__ = 'monitor'
 39 
 40     id = Column('id', Integer, primary_key=True)
 41     # device_type 1代表灭弧 2代表电气火灾
 42     device_type = Column('device_type', SmallInteger, index=True, default=1)
 43     u_id = Column('sn_num', String(10), index=True)
 44     phone_num = Column('phone_num', String(20), index=True, nullable=True)
 45     name = Column('name', String(40), index=True)
 46     position = Column('position', String(40), nullable=True)
 47     join_time = Column('join_time', DateTime, index=True)
 48     longitude = Column('longitude', DECIMAL(12, 9), default=31.000000)
 49     latitude = Column('latitude', DECIMAL(12, 9), default=121.000000)
 50     unit_id = Column('unit_id', Integer, ForeignKey('unit.id'))
 51 
 52 
 53 class Unit(Base):
 54     __tablename__ = 'unit'
 55 
 56     id = Column('id', Integer, primary_key=True)
 57     name = Column('name', String(100), index=True)
 58     address = Column('address', String(100), index=True, nullable=True)
 59     contact_person = Column('contactperson', String(30), nullable=True)
 60     contact_number = Column('contactnumber', String(30), nullable=True)
 61     device_operation_password = Column('device_operation_password', String(4), default='1234')
 62     rc_group_id = Column('rc_group_id', String(36), default=str(uuid.uuid1()))
 63     rc_group_name = Column('rc_group_name', String(50), nullable=True)
 64     longitude = Column('longitude', DECIMAL(12, 9), default=31.000000)
 65     latitude = Column('latitude', DECIMAL(12, 9), default=121.000000)
 66     active = Column('active', SmallInteger, index=True, default=0)
 67     is_group = Column('is_group', SmallInteger, index=True, default=0)
 68     parent_id = Column('parent_id', Integer, ForeignKey('unit.id'))
 69 
 70 
 71 db_session = scoped_session(sessionmaker(autocommit=False,
 72                                          autoflush=False,
 73                                          bind=engine))
 74 
 75 Base.query = db_session.query_property()
 76 
 77 
 78 def redis_2_new_sql():
 79     units_json = redis_store.lrange('units', 0, -1)
 80     units = [Unit(is_group=0, parent_id=None, **json.loads(unit_json)) for unit_json in units_json]
 81     [db_session.add(unit) for unit in units]
 82     try:
 83         db_session.commit()
 84     except Exception as e:
 85         print e
 86         db_session.rollback()
 87         return
 88 
 89     users_json = redis_store.lrange('users', 0, -1)
 90     users = [User(hidden_user=0, **json.loads(uer_json)) for uer_json in users_json]
 91     [db_session.add(user) for user in users]
 92     try:
 93         db_session.commit()
 94     except Exception as e:
 95         print e
 96         db_session.rollback()
 97         return
 98 
 99     monitors_json = redis_store.lrange('monitors', 0, -1)
100     monitors = [Monitor(**json.loads(monitor_json)) for monitor_json in monitors_json]
101     [db_session.add(monitor) for monitor in monitors]
102     try:
103         db_session.commit()
104     except Exception as e:
105         print e
106         db_session.rollback()
107         return
108 
109 if __name__ == '__main__':
110     redis_2_new_sql()

整个过程相当简单,需要注意的就是,前后顺序,因为user和monitor都有一个外键指向unit,所以要先恢复unit表,这样就不会出错了。

看来以后我有新方法搬迁数据库了。

最近公司新项目上线,需要数据库搬迁,但新版本和老版本数据库差距比较大,关系也比较复杂。如...

通过mysql自动同步redis,mysql同步redis

在服务端开发过程中,一般会使用MySQL等关系型数据库作为最终的存储引擎,Redis其实也可以作为一种键值对型的数据库,但在一些实际场景中,特别是关系型结构并不适合使用Redis直接作为数据库。这俩家伙简直可以用“男女搭配,干活不累”来形容,搭配起来使用才能事半功倍。本篇我们就这两者如何合理搭配以及他们之间数据如何进行同步展开。

一般地,Redis可以用来作为MySQL的缓存层。为什么MySQL最好有缓存层呢?想象一下这样的场景:在一个多人在线的游戏里,排行榜、好友关系、队列等直接关系数据的情景下,如果直接和MySQL正面交手,大量的数据请求可能会让MySQL疲惫不堪,甚至过量的请求将会击穿数据库,导致整个数据服务中断,数据库性能的瓶颈将掣肘业务的开发;那么如果通过Redis来做数据缓存,将大大减小查询数据的压力。在这种架子里,当我们在业务层有数据查询需求时,先到Redis缓存中查询,如果查不到,再到MySQL数据库中查询,同时将查到的数据更新到Redis里;当我们在业务层有修改插入数据需求时,直接向MySQL发起请求,同时更新Redis缓存。

在上面这种架子中,有一个关键点,就是MySQL的CRUD发生后自动地更新到Redis里,这需要通过MySQL UDF来实现。具体来说,我们把更新Redis的逻辑放到MySQL中去做,即定义一个触发器Trigger,监听CRUD这些操作,当操作发生后,调用对应的UDF函数,远程写回Redis,所以业务逻辑只需要负责更新MySQL就行了,剩下的交给MySQL UDF去完成。

一. 什么是UDF

UDF,是User Defined Function的缩写,用户定义函数。MySQL支持函数,也支持自定义的函数。UDF比存储方法有更高的执行效率,并且支持聚集函数。

UDF定义了5个API:xxx_init()、xxx_deinit()、xxx()、xxx_add()、xxx_clear()。官方文档(

图片 1

1. xxx()

这是主函数,5个函数至少需要xxx(),对MySQL操作的结果在此返回。函数的声明如下:

char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);

long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);

double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);

SQL的类型和C/C++类型的映射:

SQL Type C/C++ Type
STRING char *
INTEGER long long
REAL double

2. xxx_init()

xxx()主函数的初始化,如果定义了,则用来检查传入xxx()的参数数量、类型、分配内存空间等初始化操作。函数的声明如下:

my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

3. xxx_deinit()

xxx()主函数的反初始化,如果定义了,则用来释放初始化时分配的内存空间。函数的声明如下:

void xxx_deinit(UDF_INIT *initid);

4. xxx_add()

在聚合UDF中反复调用,将参数加入聚合参数中。函数的声明如下:

void xxx_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null,char *error);

本文由美高梅游戏平台网站发布于家常菜谱,转载请注明出处:选用redis协理mysql数据库搬迁,redismysql

关键词:

上一篇:python 文件操作总计,python文件操作总计

下一篇:没有了

最火资讯