最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL數(shù)據(jù)權(quán)限的實(shí)現(xiàn)詳情

 更新時間:2022年08月12日 08:32:01   作者:飄渺Jam  
這篇文章主要介紹了MySQL數(shù)據(jù)權(quán)限的實(shí)現(xiàn)詳情,文章通過實(shí)際案例,從代碼實(shí)戰(zhàn)的角度來實(shí)現(xiàn)這樣的一個數(shù)據(jù)權(quán)限。具體詳細(xì)介紹,具有一定的參考價值

數(shù)據(jù)權(quán)限模型

上篇文章的數(shù)據(jù)模型是基于傳統(tǒng)的RBAC模型來設(shè)計的,由于我們這里的應(yīng)用場景不一樣,所以這里的數(shù)據(jù)權(quán)限模型并沒有嚴(yán)格按照上篇文章的方案來設(shè)計,但是萬變不離其宗,核心原理還是相同的。

首先我來介紹一下我們最終實(shí)現(xiàn)的效果

實(shí)現(xiàn)效果

一個組件(可以理解成菜單)可以綁定多個授權(quán)維度,當(dāng)給角色授權(quán)組件時可以給這個授權(quán)組件賦予不同維度的權(quán)限。

關(guān)于數(shù)據(jù)權(quán)限的授權(quán)維度有以下幾個關(guān)鍵點(diǎn)需要仔細(xì)體會:

  • 給一個角色勾選授權(quán)維度實(shí)際上是在限制這個角色所能看到的數(shù)據(jù)范圍
  • 任何一個授權(quán)維度勾選了"全部",相當(dāng)于不限制此維度的權(quán)限。
    • 如果一個角色勾選了客戶群的全部 + A產(chǎn)品線,那么最終生成的sql 會是 where 產(chǎn)品線 in ('A產(chǎn)品線')
  • 如果一個角色勾選了多個維度,維度之間用 AND 拼接
    • ? 如果一個角色勾選了A客戶群 + B產(chǎn)品線,那么最終生成的sql 會是 where 客戶群 in('A客戶群')AND 產(chǎn)品線 in ('B產(chǎn)品線')
  • 一個用戶可能有多個角色,角色之間用 OR 拼接
    • ? 一個用戶有兩個角色:客戶群總監(jiān),產(chǎn)品線經(jīng)理。其中客戶群總監(jiān)角色擁有A客戶群和B客戶群的權(quán)限,產(chǎn)品線經(jīng)理角色擁有A產(chǎn)品線權(quán)限,那么最終生成的sql會是 where 客戶群 in ('A客戶群','B客戶群') OR 產(chǎn)品線 in ('A產(chǎn)品線')

當(dāng)然我們業(yè)務(wù)場景中數(shù)據(jù)規(guī)則比較單一,全部使用 in作為sql條件連接符,你們可以根據(jù)實(shí)際業(yè)務(wù)場景進(jìn)行補(bǔ)充。

數(shù)據(jù)模型

最終的數(shù)據(jù)模型如下所示:

這里的組件大家完全可以理解成RBAC模型中的資源、菜單,只不過叫法不同而已。

數(shù)據(jù)權(quán)限表結(jié)構(gòu)

下面是具體的表結(jié)構(gòu)設(shè)計

授權(quán)維度表

CREATE TABLE `wb_dimension` (
  `ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主鍵',
  `DIMENSION_CODE` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '維度編碼',
  `DIMENSION_NAME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '維度名稱',
  PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='授權(quán)維度'

具體授權(quán)維度表(產(chǎn)品線)

CREATE TABLE `wb_dimension_proc_line` (
  `ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主鍵',
  `DIMENSION_CODE` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '維度編碼',
  `PROC_LINE_CODE` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '產(chǎn)品線編碼',
  `PROC_LINE_NAME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '產(chǎn)品線名稱',
  PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='授權(quán)維度-產(chǎn)品線'

跟授權(quán)維度表實(shí)際是一個表繼承的關(guān)系,由于每個授權(quán)維度的屬性不一樣,展現(xiàn)形式也不一樣,所以分表存儲。

組件路由表

CREATE TABLE `wb_route` (
  `ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主鍵ID',
  `COMPONENT_ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '組件ID',
  `ROUTE_URL` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '路由地址',
  `AUTHORIZATION_TYPE` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '授權(quán)方式:1 自定義,2 上下級授權(quán), 3 范圍授權(quán)',
  `AUTHORIZATION_DIMENSION` json DEFAULT NULL COMMENT '授權(quán)維度',
  PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='組件路由'
復(fù)制代碼

當(dāng)組件屬性授權(quán)方式為范圍授權(quán)時在應(yīng)用側(cè)會強(qiáng)制要求選擇具體的授權(quán)維度,如 產(chǎn)品線、客戶群。

角色表

CREATE TABLE `wb_role` (
  `ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主鍵ID',
  `ROLE_CODE` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '角色CODE',
  `ROLE_NAME` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '角色名稱',
  `IDENTITY_ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '身份ID'
  PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='角色表'

角色上有一個身份屬性,多個角色可以歸屬同一個身份,方便對角色進(jìn)行分類管理。

角色組件綁定表

CREATE TABLE `role_component_relation` (
  `ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主鍵ID',
  `ROLE_ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '角色I(xiàn)D',
  `COMPONENT_ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '組件ID',
  PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='角色授權(quán)組件'

角色組件授權(quán)規(guī)則表(核心)

CREATE TABLE `wb_role_component_rule` (
  `ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '主鍵',
  `ROLE_ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '角色I(xiàn)D',
  `COMPONENT_ID` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '組件ID',
  `RULE_CODE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '規(guī)則編碼',
  `RULE_NAME` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '規(guī)則名稱',
  `RULE_CONDITION` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '規(guī)則條件',
  `RULE_VALUE` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '規(guī)則值',
  PRIMARY KEY (`ID`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='角色組件維度規(guī)則表'

數(shù)據(jù)權(quán)限的核心表,規(guī)則條件的取值為IN,規(guī)則值存儲具體的維度編碼,當(dāng)在數(shù)據(jù)維度中選擇 全部 時我們將規(guī)則值存儲為ALL這個特殊值,方便后續(xù)生成SQL語句。

實(shí)現(xiàn)過程

  • 自定義一個數(shù)據(jù)權(quán)限的注解,比如叫DataPermission
  • 在對應(yīng)的資源請求方法,比如商機(jī)列表上添加自定義注解@DataPermission
  • 利用AOP抓取到用戶對應(yīng)角色的所有數(shù)據(jù)規(guī)則并進(jìn)行SQL拼接,最終在SQL層面實(shí)現(xiàn)數(shù)據(jù)過濾。

代碼實(shí)現(xiàn)

自定義數(shù)據(jù)權(quán)限注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
@Documented
public @interface DataPermission {
	/**
	 * 數(shù)據(jù)權(quán)限類型
	 * 1 上下級授權(quán)  2 數(shù)據(jù)范圍授權(quán)
	 */
	String permissionType() default "2";
	
	/**
	 * 配置菜單的組件路徑,用于數(shù)據(jù)權(quán)限
	 */
	String componentRoute() default "";
}

定義數(shù)據(jù)權(quán)限處理切面

@Aspect
@Slf4j
public class DataPermissionAspect {

	@Autowired
	private RoleComponentRuleService roleComponentRuleService;

	@Pointcut("@annotation(com.ifly.workbench.security.annotation.DataPermission)")
	public void pointCut() {
		
	}
	
	@Around("pointCut()")
	public Object around(ProceedingJoinPoint point) throws  Throwable{

		HttpServletRequest request = SpringContextUtils.getHttpServletRequest();

		//獲取請求token
		String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN);
		String userName = JwtUtil.getUsername(token);
    
		MethodSignature signature = (MethodSignature) point.getSignature();
		Method method = signature.getMethod();
		DataPermission permissionData = method.getAnnotation(DataPermission.class);

    //獲取授權(quán)方式
		String permissionType = permissionData.permissionType();
		//獲取組件路由
		String componentRoute = permissionData.componentRoute();
    
    if (StringUtils.isNotEmpty(componentRoute)){
			// 查找當(dāng)前用戶此組件下的所有規(guī)則
			List<RoleComponentRuleDTO> componentRules = roleComponentRuleService.getRoleComponentRule(userName, componentRoute);
      
			if(CollectionUtils.isNotEmpty(componentRules)){
					DataPermissionUtils.installDataSearchConditon(request, componentRules);
					SysUserCacheInfo userInfo = buildCacheUser(userName);
					DataPermissionUtils.installUserInfo(request, userInfo);
				}
		}
    
    return  point.proceed();
	}

	private SysUserCacheInfo buildCacheUser(String userName) {
		SysUserCacheInfo info = new SysUserCacheInfo();
		info.setSysUserName(userName);
		info.setOneDepart(true);
		return info;
	}
}

在AOP中獲取當(dāng)前用戶、需要訪問的組件中所有的數(shù)據(jù)規(guī)則,參考wb_role_component_rule表設(shè)計,并將其放到Request作用域中。

數(shù)據(jù)權(quán)限工具類

public class DataPermissionUtils {
	public static final String COMPONENT_DATA_RULES = "COMPONENT_DATA_RULES";

	public static final String SYS_USER_INFO = "SYS_USER_INFO";
   /**
	 * 往鏈接請求里面,傳入數(shù)據(jù)查詢條件
	 * @param request
	 * @param componentRules
	 */
	public static void installDataSearchConditon(HttpServletRequest request, List<RoleComponentRuleDTO> componentRules) {
		// 1.先從request獲取MENU_DATA_AUTHOR_RULES,如果存則獲取到LIST
		List<RoleComponentRuleDTO> list = loadDataSearchCondition();

		if (list==null) {
			// 2.如果不存在,則new一個list
			list = Lists.newArrayList();
		}
		list.addAll(componentRules);
		// 3.往list里面增量存指
		request.setAttribute(COMPONENT_DATA_RULES, list);
	}

	/**
	 * 獲取請求對應(yīng)的數(shù)據(jù)權(quán)限規(guī)則
	 *
	 */
	@SuppressWarnings("unchecked")
	public synchronized List<RoleComponentRuleDTO> loadDataSearchCondition() {
		return (List<RoleComponentRuleDTO>) SpringContextUtils.getHttpServletRequest().getAttribute(COMPONENT_DATA_RULES);
				
	}
	
	public synchronized void installUserInfo(HttpServletRequest request, SysUserCacheInfo userinfo) {
		request.setAttribute(SYS_USER_INFO, userinfo);
	}
}

在Request中存儲數(shù)據(jù)規(guī)則。

查詢組件規(guī)則

public interface RoleComponentRuleService extends IService<RoleComponentRule> {

    /**
     * 根據(jù) 用戶域賬戶和組件編碼 獲取組件對應(yīng)的關(guān)系
     *
     * @param userName      域賬號
     * @param componentCode 組件編碼
     * @return 用戶的所有規(guī)則
     */
    List<RoleComponentRuleDTO> getRoleComponentRule(String userName, String componentCode);
}
@Service
public class RoleComponentRuleServiceImpl extends ServiceImpl<RoleComponentRuleMapper, RoleComponentRule> implements RoleComponentRuleService {

    @Resource
    private RoleComponentRuleMapper roleComponentRuleMapper;

    /**
     * 根據(jù) 用戶域賬戶和組件編碼 獲取組件對應(yīng)的關(guān)系
     * @param userName      域賬號
     * @param componentCode 組件編碼
     * @return 用戶的所有規(guī)則
     */
    @Override
    public List<RoleComponentRuleDTO> getRoleComponentRule(String userName, String componentCode) {
        return roleComponentRuleMapper.getRoleComponentRule(userName,componentCode);
    }

}
<select id="getRoleComponentRule" resultType="com.ifly.vo.RoleComponentRuleDTO">
	SELECT
    tab1.id,
    tab1.role_id,
    tab4.role_code,
    tab1.component_id,
    tab1.rule_code,
    tab1.rule_name,
    tab1.rule_condition,
    tab1.rule_value,
    tab4.identity_id
  FROM
  	wb_role_component_rule tab1
  	LEFT JOIN user_role_relation tab2 ON tab2.role_id = tab1.role_id
  	LEFT JOIN wb_component tab3 ON tab3.id = tab1.component_id
  	LEFT JOIN wb_role tab4 ON tab4.id = tab1.role_id
  	JOIN role_component_relation tab5 ON tab5.role_id = tab1.role_id
  	AND tab5.component_id = tab1.component_id
  where
  	tab2.user_account = #{userName}
  	and tab3.component_code = #{componentCode}
</select>

Controller調(diào)用

@ApiOperation(value = "服務(wù)BU-領(lǐng)導(dǎo)-總覽")
@GetMapping("opp/getLeaderOverviewSve")
@DataPermission(componentRoute = "020202")
public Result<SalesProjOverviewSve> getLeaderOverviewSve(@RequestParam(name = "identityId") String identityId) {
	String permissionSql = RuleQueryGenerator.getPermissionSql(identityId);
  log.info("查服務(wù)BU-領(lǐng)導(dǎo)-總覽-permissionSQL==" + permissionSql);

	return Result.OK(overviewSveService.getLeaderOverviewSve(permissionSql));
}

在controller的請求方法上加上自定義注解@DataPermission并指定組件編碼,然后通過工具類生成SQL條件,最后將SQL條件傳入service層進(jìn)行處理。

構(gòu)建數(shù)據(jù)權(quán)限SQL

@Slf4j
@UtilityClass
public class RuleQueryGenerator {

    private static final String SQL_AND = " and ";

    private static final String SQL_OR = " or ";

    private static final String SQL_JOINT = " (%s) ";

    /**
     * 獲取帶有數(shù)據(jù)權(quán)限的SQL
     * @param identityId 身份ID
     */
    public String getPermissionSql(String identityId) {
        //------------------------獲取當(dāng)前身份的數(shù)據(jù)規(guī)則------------------------------------
        List<RoleComponentRuleDTO> conditionList = getCurrentIdentyPermission(identityId);
        if (CollectionUtils.isEmpty(conditionList)) {
            //沒有權(quán)限
            return "1 = 0";
        }
        //存在權(quán)限
        //對當(dāng)前身份根據(jù)規(guī)則編碼分組-去除不同角色中相同編碼且規(guī)則值為ALL的規(guī)則 并根據(jù)角色id分組
        Map<String, List<RoleComponentRuleDTO>> ruleMap = getRuleMapByRoleId(conditionList);

        StringBuilder sb = new StringBuilder();
        String roleSql;
        if (MapUtils.isNotEmpty(ruleMap)) {
            //按角色拼接SQL
            for (Map.Entry<String, List<RoleComponentRuleDTO>> entry : ruleMap.entrySet()) {

                List<RoleComponentRuleDTO> lists = entry.getValue();

                // 同角色之間使用 AND
                roleSql = buildRoleSql(lists);

                //角色之間使用 OR
                if (StringUtils.isNotEmpty(roleSql)) {
                    jointSqlByRoles(sb, roleSql);
                }
            }

        }
        return sb.toString();
    }

    private static List<RoleComponentRuleDTO> getCurrentIdentyPermission(String identityId) {
        //----------------------------獲取所有數(shù)據(jù)規(guī)則-----------------------------
        List<RoleComponentRuleDTO> roleRuleList = DataPermissionUtils.loadDataSearchCondition();
        if(CollectionUtils.isEmpty(roleRuleList)){
            return null;
        }
        //-----------------------------過濾掉不屬于當(dāng)前身份的規(guī)則-----------------------------------
        return roleRuleList.stream()
                .filter(item -> item.getIdentityId().equals(identityId))
                .collect(Collectors.toList());
    }

    /**
     * 構(gòu)建單角色SQL
     */
    private static String buildRoleSql(List<RoleComponentRuleDTO> lists) {
        StringBuilder roleSql = new StringBuilder();
        for (RoleComponentRuleDTO item : lists) {
            //如果出現(xiàn)全選 則 代表全部,不需要限定范圍
            if ("ALL".equals(item.getRuleValue())) {
                continue;
            }
            //將規(guī)則轉(zhuǎn)換成SQL
            String filedSql = convertRuleToSql(item);

            roleSql.append(SQL_AND).append(filedSql);
        }
        return roleSql.toString();
    }


    /**
     * 將單一規(guī)則轉(zhuǎn)化成SQL,默認(rèn)全部使用 In
     * ruleCode : area_test
     * ruleValue : 區(qū)域1,區(qū)域2,區(qū)域3
     * @param rule 規(guī)則值
     */
    private static String convertRuleToSql(RoleComponentRuleDTO rule) {
        String whereCondition = " in ";
        String ruleValueConvert = getInConditionValue(rule.getRuleValue());
        return rule.getRuleCode() + whereCondition + ruleValueConvert;
    }


    /**
     * IN字符串轉(zhuǎn)換
     * 區(qū)域1, 區(qū)域2, 區(qū)域3  --> ("區(qū)域1","區(qū)域2","區(qū)域3")
     * 江西大區(qū)  --> ("江西大區(qū)")
     */
    private static String getInConditionValue(String ruleValue) {
        String[] temp = ruleValue.split(",");
        StringBuilder res = new StringBuilder();
        for (String string : temp) {
            res.append(",'").append(string).append("'");
        }
        return "(" + res.substring(1) + ")";
    }

    /**
     * 拼接單角色的SQL
     * @param sqlBuilder 總的SQL
     * @param roleSql    單角色SQL
     */
    private static void jointSqlByRoles(StringBuilder sqlBuilder, String roleSql) {
        roleSql = roleSql.replaceFirst(SQL_AND, "");
        if (StringUtils.isEmpty(sqlBuilder.toString())) {
            sqlBuilder.append(String.format(SQL_JOINT, roleSql));
        } else {
            sqlBuilder.append(SQL_OR).append(String.format(SQL_JOINT, roleSql));
        }
    }

    /**
     *
     * 1. 對當(dāng)前身份根據(jù)規(guī)則編碼分組-去除不同角色中相同編碼且規(guī)則值為ALL的規(guī)則
     * 2. 對角色進(jìn)行分組
     * @param conditionList 數(shù)據(jù)規(guī)則
     * @return 分組后的規(guī)則list
     */
    private static Map<String, List<RoleComponentRuleDTO>> getRuleMapByRoleId(List<RoleComponentRuleDTO> conditionList) {
    //--------過濾掉不屬于當(dāng)前身份的規(guī)則,并對條件編碼進(jìn)行分組-----------------------------------
    Map<String, List<RoleComponentRuleDTO>> conditionMap = conditionList.stream().collect(Collectors.groupingBy(RoleComponentRuleDTO::getRuleCode));

		//--------相同編碼分組中存在ALL的排除掉-----------------------------------------------
    List<RoleComponentRuleDTO> newRoleRuleList = new ArrayList<>();
    if (MapUtils.isNotEmpty(conditionMap)) {
    	for (Map.Entry<String, List<RoleComponentRuleDTO>> entry : conditionMap.entrySet()) {
      	boolean flag = true;
        List<RoleComponentRuleDTO> lists = entry.getValue();
        for (RoleComponentRuleDTO item : lists) {
        	if ("ALL".equals(item.getRuleValue())) {
          	flag = false;
            break;
          }
        }
        
        if (flag) {
           newRoleRuleList.addAll(lists);
        }
     	}
     }
     if (CollectionUtils.isNotEmpty(newRoleRuleList)) {
        return newRoleRuleList.stream().collect(Collectors.groupingBy(RoleComponentRuleDTO::getRoleId));
      }
     return Maps.newHashMap();
    }
}

核心類,用于生成數(shù)據(jù)權(quán)限查詢的SQL腳本。

Dao層實(shí)現(xiàn)

<select id="getLeaderOverviewSve" resultType="com.ifly.center.entity.SalesProjOverviewSve">
	SELECT <include refid="column_list"/>  FROM U_STD_ADS.LTC_SALES_PROJ_OVERVIEW_SVE
  <where>
  	<if test="permissionSql != null and permissionSql != ''">
  		${permissionSql}
    </if>
 	</where>
</select>

Dao層接受service層傳入已經(jīng)生成好的sql語句,作為查詢條件直接拼接在業(yè)務(wù)語句之后。

小結(jié)

以上,就是數(shù)據(jù)權(quán)限的實(shí)現(xiàn)過程,其實(shí)代碼實(shí)現(xiàn)并不復(fù)雜,主要還是得理解其中的實(shí)現(xiàn)原理。如果你也有數(shù)據(jù)權(quán)限的需求,不妨參考一下。

到此這篇關(guān)于MySQL數(shù)據(jù)權(quán)限的實(shí)現(xiàn)詳情的文章就介紹到這了,更多相關(guān)SQL數(shù)據(jù)權(quán)限內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mysql中insert并發(fā)問題(on?DUPLICATE?KEY?UPDATE)

    mysql中insert并發(fā)問題(on?DUPLICATE?KEY?UPDATE)

    本文主要介紹了mysql中insert并發(fā)問題(on?DUPLICATE?KEY?UPDATE),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • MySQL8.0?索引優(yōu)化invisible?index詳情

    MySQL8.0?索引優(yōu)化invisible?index詳情

    這篇文章主要介紹了MySQL8.0?索引優(yōu)化invisible?index詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • MySQL單表存多大的數(shù)據(jù)量比較合適

    MySQL單表存多大的數(shù)據(jù)量比較合適

    MySQL數(shù)據(jù)庫在處理大規(guī)模數(shù)據(jù)時,性能會受到影響,這時候就需要考慮分庫分表策略,本文就來介紹一下MySQL單表存多大的數(shù)據(jù)量比較合適,感興趣的可以了解一下
    2024-11-11
  • Mysql中in和exists的區(qū)別?&?not?in、not?exists、left?join的相互轉(zhuǎn)換問題

    Mysql中in和exists的區(qū)別?&?not?in、not?exists、left?join的相互轉(zhuǎn)換問題

    這篇文章主要介紹了Mysql中in和exists的區(qū)別?&?not?in、not?exists、left?join的相互轉(zhuǎn)換,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • MySQL關(guān)鍵字IN與EXISTS的使用與區(qū)別詳解

    MySQL關(guān)鍵字IN與EXISTS的使用與區(qū)別詳解

    in和exists是兩種常用的條件查詢關(guān)鍵字,兩種常用于子查詢,它們在某些情況下可以互換使用,但它們的工作方式和效率可能會有所不同,這篇文章主要給大家介紹了關(guān)于MySQL關(guān)鍵字IN與EXISTS的使用與區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2024-09-09
  • MySQL數(shù)據(jù)庫Shell import_table數(shù)據(jù)導(dǎo)入

    MySQL數(shù)據(jù)庫Shell import_table數(shù)據(jù)導(dǎo)入

    本文我們介紹一款高效的數(shù)據(jù)導(dǎo)入工具,MySQL Shell 工具集中的import_table,該工具的全稱是Parallel Table Import Utility,需要的朋友請參考下文
    2021-08-08
  • 101個MySQL的配置和優(yōu)化的提示

    101個MySQL的配置和優(yōu)化的提示

    這里是101條調(diào)節(jié)和優(yōu)化 MySQL安裝的技巧。一些技巧是針對特定的安裝環(huán)境的,但這些思路是通用的。我已經(jīng)把他們分成幾類,來幫助你掌握更多MySQL的調(diào)節(jié)和優(yōu)化技巧
    2013-08-08
  • MySQL5.6安裝步驟圖文詳解

    MySQL5.6安裝步驟圖文詳解

    這篇文章主要為大家詳細(xì)介紹了MySQL安裝步驟配置方法圖文,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 使用mysqldump如何實(shí)現(xiàn)數(shù)據(jù)庫表備份

    使用mysqldump如何實(shí)現(xiàn)數(shù)據(jù)庫表備份

    這篇文章主要介紹了使用mysqldump如何實(shí)現(xiàn)數(shù)據(jù)庫表備份方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2013-06-06
  • 在MySQLDump中使用-w語句進(jìn)行備份的方法

    在MySQLDump中使用-w語句進(jìn)行備份的方法

    這篇文章主要介紹了在MySQLDump中使用-w語句進(jìn)行備份的方法,MySQLDump是一款很有人氣的MySQL數(shù)據(jù)轉(zhuǎn)存工具,需要的朋友可以參考下
    2015-05-05

最新評論

伊金霍洛旗| 铜陵市| 伊吾县| 庄河市| 岳阳县| 阜宁县| 仙游县| 恩施市| 班戈县| 肇源县| 梁河县| 封丘县| 穆棱市| 河津市| 涿鹿县| 安仁县| 鹿邑县| 淮北市| 资中县| 天峻县| 越西县| 闵行区| 金山区| 明星| 宜兰县| 安泽县| 灌南县| 凤翔县| 襄城县| 永德县| 毕节市| 南乐县| 桃源县| 太保市| 报价| 襄樊市| 托克逊县| 年辖:市辖区| 承德县| 天镇县| 陆良县|