python

利用位运算实现一个字段表示多个属性_tianmlin1的博客-CSDN博客

文章暂存

systemime
2021-04-27
5 min

摘要.

# 前言

在数据库设计中,经常出现这样一种场景,如:某个系统的用户表,现阶段用户存在【是否新手】、【是否风险评测】、【是否实名认证】、【是否投资】等四个并存的属性,那么你会怎么设计表结构呢,在用户表定义四个字段?当然这样肯定是可行的,但是你设想这样一个问题,随着业务的扩展,用户可能会增加其他的属性比如【是否 vip】等等属性,那岂不是还需要 alter 用户表结构,这种修改表结构不仅影响性能同时修改的地方很多,维护成本比较高。

这里提供一种优雅的设计,通过一个字段来维护多个并存的属性。

# 设计思路

# 数据库表

用户表不用设计五个字段表示五种属性,用一个 user_propery 字段来表示用户属性,数据类型采用 bigint,因为 bigint 对应的是 java 中的 long 类型,long 类型的最大值是 2^63,也就是用 long 类型最多可以并行表示 63 个位状态,也就是可以同时表示 63 个并行的用户属性。

# 用户属性枚举

定义一个枚举类,如下:

package com.whfax.user.inf.constants;public enum UserProperty {    OPEN_ACCOUNT_FLAG(1, "1-开户成功"),    FDD_FLAG(1 << 1, " 2-法大大签约成功"),    RISK_FLAG(1 << 2, "4-风险测评成功"),    NEW_FLAG(1 << 3, "8-新手");    UserProperty(long value, String desc) {public static String getDesc(long value) {for (UserProperty property : UserProperty.values()) {if (property.value == value) {public static boolean isOpenAccountFlag(long flag) {return (flag & OPEN_ACCOUNT_FLAG.value) == OPEN_ACCOUNT_FLAG.value;public static boolean isFddFlag(long flag) {return (flag & FDD_FLAG.value) == FDD_FLAG.value;public static boolean isRiskFlag(long flag) {return (flag & RISK_FLAG.value) == RISK_FLAG.value;public static boolean isNewFlag(long flag) {return (flag & NEW_FLAG.value) == NEW_FLAG.value;

这种方式扩展性就很好了,后面随着业务扩展,只需要在这个枚举类中增加对应的属性就行了。

# dao层操作用户属性

  • 增加用户属性操作
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void addUserProperty(long userId, UserProperty userProperty) {        log.info("addUserProperty enter,userId:{}--userProperty:{}", userId, userProperty);        String update = "update " + TableNameContants.TABLE_USER                        + " set user_property=(user_property|?) ,update_time=now() where id=?";        List<Object> para = new ArrayList();        para.add(userProperty.value);        log.info("update:{}--para:{}", update, para.toArray());        mainDao.update(update, para.toArray());
  • 剔除用户属性
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public void removeUserProperty(long userId, UserProperty userProperty) {        log.info("removeUserProperty enter,userId:{}--userProperty:{}", userId, userProperty);        List<Object> para = new ArrayList();        String update = "update " + TableNameContants.TABLE_USER                        + " set user_property=(user_property&(~?)) ,update_time=now() where id=?";        para.add(userProperty.value);        log.info("update:{}--para:{}", update, para.toArray());        mainDao.update(update, para.toArray());

# 说明

上次编辑于: 5/20/2021, 7:26:49 AM