精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

基于 sharding-jdbc 拓展點(diǎn)實(shí)現(xiàn)復(fù)雜分庫分表算法

開發(fā)
本文就以一個基于電話號碼號頭的案例介紹一下如何通過基于sharding-jdbc拓展點(diǎn)實(shí)現(xiàn)復(fù)雜分庫分表算法。

我們之前介紹一款輕量級的分庫分表中間件sharding-jdbc,默認(rèn)情況下該框架的分表算法都是采用內(nèi)聯(lián)表達(dá)式進(jìn)行配置,對于某些比較靈活的需求無法實(shí)現(xiàn),所以本文就以一個基于電話號碼號頭的案例介紹一下如何通過基于sharding-jdbc拓展點(diǎn)實(shí)現(xiàn)復(fù)雜分庫分表算法。

一、詳解自定義分表邏輯開發(fā)

1. 基于復(fù)雜發(fā)表算法的案例說明

我們的案例是為了采集不同地區(qū)的電話號碼用戶的信息,希望相同號頭的電話號碼會落到同一張分表上,例如我們現(xiàn)在有分表3張,有一個電話號碼10658888,我們必須截取到1065和分表數(shù)進(jìn)行取模運(yùn)算得到分表名user_0:

2. 基于源碼了解拓展點(diǎn)

我們直接定位到框架進(jìn)行分庫分表計算的代碼段StandardRoutingEngine的routeTables,可以看到該方法會通過程序初始化加載好的shardingRule定位到當(dāng)前分表策略:

private Collection<DataNode> routeTables(final TableRule tableRule, final String routedDataSource, final List<RouteValue> tableShardingValues) {
  //獲取分表的前綴,以本文為例就是user
        Collection<String> availableTargetTables = tableRule.getActualTableNames(routedDataSource);
        //基于shardingRule調(diào)用getTableShardingStrategy獲取分表策略
        Collection<String> routedTables = new LinkedHashSet<>(tableShardingValues.isEmpty() ? availableTargetTables
                : shardingRule.getTableShardingStrategy(tableRule).doSharding(availableTargetTables, tableShardingValues));
        Preconditions.checkState(!routedTables.isEmpty(), "no table route info");
        Collection<DataNode> result = new LinkedList<>();
        for (String each : routedTables) {
            result.add(new DataNode(routedDataSource, each));
        }
        return result;
    }

查看getTableShardingStrategy方法可以看到,如果tableRule沒有實(shí)現(xiàn)默認(rèn)分表策略,則采用默認(rèn)也就是我們配置的內(nèi)斂策略defaultTableShardingStrategy ,反之返回我們自定義實(shí)現(xiàn)的分表策略:

public ShardingStrategy getTableShardingStrategy(final TableRule tableRule) {
   //若getTableShardingStrategy返回空說明我們沒有自定義實(shí)現(xiàn)類,返回defaultTableShardingStrategy 通過內(nèi)聯(lián)表達(dá)式進(jìn)行分表運(yùn)算,反之返回我們的自定義實(shí)現(xiàn)類
        return null == tableRule.getTableShardingStrategy() ? defaultTableShardingStrategy : tableRule.getTableShardingStrategy();
    }

此時我們可以推測tableShardingStrategy的配置就決定了我們是走內(nèi)聯(lián)表達(dá)式還是自定義類分表算法,通過源碼的定位筆者發(fā)現(xiàn)tableShardingStrategy關(guān)于分表的配置來源于配置,在程序啟動時tableShardingStrategy會根據(jù)yml的配置得到分表前綴如果是.table-strategy.standard.則說明當(dāng)前程序采用的是自定義分表算法,就會基于這段配置定位到Java類生分表引擎:

對應(yīng)的我們給出分表算法初始化的入口:

public TableRule(final TableRuleConfiguration tableRuleConfig, final ShardingDataSourceNames shardingDataSourceNames, final String defaultGenerateKeyColumn) {
        //......
        //基于配置的值決定分表算法如何創(chuàng)建
        tableShardingStrategy = null == tableRuleConfig.getTableShardingStrategyConfig() ? null : ShardingStrategyFactory.newInstance(tableRuleConfig.getTableShardingStrategyConfig());
        //......
    }

繼續(xù)步進(jìn)我們就可以直接定位到對應(yīng)分表配置加載邏輯:

@Override
    public TableRuleConfiguration swap(final YamlTableRuleConfiguration yamlConfiguration) {
      //......
            
  //基于yml配置得到分表算法采用哪種方式            
  result.setTableShardingStrategyConfig(shardingStrategyConfigurationYamlSwapper.swap(yamlConfiguration.getTableStrategy()));
 
        //......
        return result;
    }

最終查看配置加載的swap就可以看到自定分表配置加載的邏輯可以看到,只要我們配置的是StandardShardingStrategyConfiguration前綴的配置,這段配置就會為我們生成自定義算法:

@Override
    public YamlShardingStrategyConfiguration swap(final ShardingStrategyConfiguration data) {
    //基于yml中給定的字段、分表類生成標(biāo)準(zhǔn)的分表策略配置
    StandardShardingStrategyConfiguration得到自定義分表算法
        YamlShardingStrategyConfiguration result = new YamlShardingStrategyConfiguration();
        if (data instanceof StandardShardingStrategyConfiguration) {
            result.setStandard(createYamlStandardShardingStrategyConfiguration((StandardShardingStrategyConfiguration) data));
        }
       //......
        return result;
    }

3. 配置與分表算法實(shí)現(xiàn)

基于上述源碼,筆者得到對應(yīng)配置前綴,我們開始進(jìn)行自定義分庫分表算法的配置步驟,首先自然是完成數(shù)據(jù)源的配置,如下所示,筆者自定義分表數(shù)據(jù)源名稱為ds0,后續(xù)數(shù)據(jù)源信息配置的datasource后面都要拼上這個自定義的數(shù)據(jù)源名稱ds0:

# 數(shù)據(jù)源名稱
spring.shardingsphere.datasource.names=ds0
# 數(shù)據(jù)源基本鏈接、賬號、密碼信息
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/db?characterEncoding=utf-8
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456

完成數(shù)據(jù)源基本配置后就到最重要分表核心配置了,對應(yīng)選項(xiàng)含義分別是:

  • actual-data-nodes:配置分庫分表的庫表區(qū)間,以筆者為例,配置為單庫多表,對應(yīng)的配置為ds0.user_$->{0..2},即ds0這個數(shù)據(jù)源下的user_0、user_1、user_2。
  • precise-algorithm-class-name:指定分庫分表的策略的實(shí)現(xiàn)類的全路徑,以筆者為例包的全路徑為com.sharkChili.algorithm.TableShardingAlgorithm。
  • sharding-column:配置分片鍵,本文采用的是用戶表的電話號碼也就是phone字段。
  • key-generator.column:該表的主鍵id為id。
  • key-generator.type:id算法采用雪花算法。
# 配置分表區(qū)間
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds0.user_$->{0..2}
# 指定自定義分表類的包全路徑
spring.shardingsphere.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.sharkChili.algorithm.TableShardingAlgorithm
# 配置分表分片鍵
spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=phone
# 配置主鍵生成策略,指定數(shù)據(jù)表的主鍵為id字典,id算法采用雪花算法
spring.shardingsphere.sharding.tables.user.key-generator.column=id
# id使用雪花算法,因?yàn)檠┗ㄋ惴ㄉ傻膇d具有全球唯一性,并且又有自增特性,適合mysql的innodb引擎
spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE

如果我們希望打印分庫分表執(zhí)行SQL日志可以加上這條配置:

# 打開sql輸出日志
spring.shardingsphere.props.sql.show=true

最后我們給出分表實(shí)現(xiàn)類,直接繼承PreciseShardingAlgorithm并執(zhí)行泛型為phone字典的類型String,通過截取電話號碼頭4位通過取模算法返回分表名稱:

@Slf4j
public class TableShardingAlgorithm implements PreciseShardingAlgorithm<String> {


    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<String> phoneNum) {
        log.info("分表信息:{}", JSONUtil.toJsonStr(collection));

        //號頭小于4位,放到默認(rèn)表
        if (StrUtil.isEmpty(phoneNum.getValue()) || phoneNum.getValue().length() < 4) {
            return "user";
        }
        //獲取號頭進(jìn)行取模獲取表號
        String phonePrex = phoneNum.getValue().substring(0, 4);
        int tableNo = (Integer.valueOf(phonePrex)) % collection.size();
        log.info("preciseShardingValue:{} table no:{}", phoneNum, tableNo);
        //返回分表名
        return "user_" + tableNo;
    }
}

4. 自定義分表算法演示

最后我們給出插入的測試代碼:

@Test
    void insert() {

        User user = new User();
        user.setId((long) RandomUtil.randomInt());
        user.setName("user" + 7879879843L);
        user.setPhone("10658888");
        userMapper.insert(user);
    }

從日志可以看出,我們的插入數(shù)據(jù)定位到了分表0,與預(yù)期一致:

INFO 11940 --- [           main] ShardingSphere-SQL                       : Actual SQL: ds0 ::: insert into user_0  (id, name, phone) VALUES (?, ?, ?) ::: [-1687644961, user7879879843, 10658888]

二、詳解Sharding-JDBC幾種分片策略

1. Sharding-JDBC分片策略概覽

上述代碼我們已經(jīng)通過inline關(guān)鍵字指明基于表達(dá)式user_$->{id % 3}所實(shí)現(xiàn)的內(nèi)聯(lián)策略,通過該配置與之關(guān)聯(lián)的關(guān)系類YamlShardingStrategyConfiguration我們可以看出,Sharding-JDBC總共一共了如下幾種分片策略:

  • standard:精確分片策略,即基于用戶給定的單個分片鍵定位對應(yīng)的庫表。
  • complex:復(fù)雜分片策略,即基于用戶傳入的多個字段定位對應(yīng)的庫表。
  • hint:強(qiáng)制路由策略,比較少用,該策略用基于用戶傳參并結(jié)合路由策略實(shí)現(xiàn)類定位庫表。
  • inline:內(nèi)聯(lián)表達(dá)式,基于用戶給定的分片鍵值和表達(dá)式獲取對應(yīng)的庫表。
  • none:無分片策略。

對應(yīng)的我們給出YamlShardingStrategyConfiguration 的配置類印證這種說法:

@Getter
@Setter
public class YamlShardingStrategyConfiguration implements YamlConfiguration {
    
    private YamlStandardShardingStrategyConfiguration standard;
    
    private YamlComplexShardingStrategyConfiguration complex;
    
    private YamlHintShardingStrategyConfiguration hint;
    
    private YamlInlineShardingStrategyConfiguration inline;
    
    private YamlNoneShardingStrategyConfiguration none;
}

2. 標(biāo)準(zhǔn)分片策略(范圍分片)

我們先來說說標(biāo)準(zhǔn)分片策略,也就是我們上文所實(shí)現(xiàn)的自定義分片算法,這里我們介紹另一種基于范圍分片的策略實(shí)現(xiàn),如下所示,可以看到我們分片鍵為user表的id之后,指明range-algorithm-class-name即范圍分片查詢算法的實(shí)現(xiàn)類為TableRangeShardingAlgorithm:

spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=id

# 指明user表的范圍分片算法類為TableRangeShardingAlgorithm
spring.shardingsphere.sharding.tables.user.table-strategy.standard.range-algorithm-class-name=com.sharkChili.algorithm.TableRangeShardingAlgorithm

對應(yīng)我們也給出范圍分片實(shí)現(xiàn)的算法實(shí)現(xiàn)類TableRangeShardingAlgorithm :

@Slf4j
public class TableRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<Long> rangeShardingValue) {
        //記錄分片鍵對應(yīng)的分表
        Set<String> resTbSet = new ConcurrentHashSet<>();
        //獲取id起始值
        long begin = rangeShardingValue.getValueRange().lowerEndpoint();
        //獲取id結(jié)束值
        long end = rangeShardingValue.getValueRange().upperEndpoint();
        //基于這個id的范圍取模定位分表名稱寫入set中
        LongStream.rangeClosed(begin, end).forEach(i -> resTbSet.add("user_" + i % 3));

        log.info("res tb set:{}", resTbSet);
        return resTbSet;
    }
}

這里我們給出測試代碼:

UserMapper userMapper = SpringUtil.getBean(UserMapper.class);
        UserExample userExample = new UserExample();
        //指明id為2、3對應(yīng)算法%3后的分表為0、1
         userExample.createCriteria()
                .andIdBetween(2L, 3L);

        List<User> userList = userMapper.selectByExample(userExample);
        log.info("user list:{}", userList);

輸出結(jié)果如下,可以看到定位到了0和3兩個分表,與預(yù)期的邏輯一致:

需要補(bǔ)充的是范圍分片和標(biāo)準(zhǔn)精準(zhǔn)匹配的分片策略是兼容的,所以我們在標(biāo)準(zhǔn)分片的配置情況下可以同時實(shí)現(xiàn)兩套算法針對不同維度的查詢:

# 標(biāo)準(zhǔn)分片策略
spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=id
# 標(biāo)準(zhǔn)分片的精準(zhǔn)定位算法
spring.shardingsphere.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.sharkChili.algorithm.TableShardingAlgorithm
# 指明user表的范圍分片算法類為TableRangeShardingAlgorithm
spring.shardingsphere.sharding.tables.user.table-strategy.standard.range-algorithm-class-name=com.sharkChili.algorithm.TableRangeShardingAlgorithm

3. 復(fù)雜分片策略

涉及多字段條件的查詢,sharding-jdbc同樣提供了復(fù)雜分片策略配置,例如我們的分表查詢算法的是基于id和age兩個字段,那么我們就可以指明complex聲明分片鍵為id和age,通過ComplexTableShardingAlgorithm實(shí)現(xiàn)分表邏輯:

# 指名復(fù)雜分片算法鍵為id和age
spring.shardingsphere.sharding.tables.user.table-strategy.complex.sharding-columns=id,age
# 復(fù)合分片算法
spring.shardingsphere.sharding.tables.user.table-strategy.complex.algorithm-class-name=com.sharkChili.algorithm.ComplexTableShardingAlgorithm

這里為了簡單演示復(fù)雜分片算法的實(shí)現(xiàn)和使用,筆者簡單的取出多值查詢中id和age各一個,然后定位到分表集合,對應(yīng)邏輯如下,讀者可以參考注釋了解一下邏輯,對應(yīng)的我們查詢時只需傳入id和age后就會走到該算法,這里就不多做結(jié)果演示了:

public class ComplexTableShardingAlgorithm implements ComplexKeysShardingAlgorithm<Long> {
    @Override
    public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Long> complexKeysShardingValue) {
        Map<String, Collection<Long>> map = complexKeysShardingValue.getColumnNameAndShardingValuesMap();
        Collection<Long> idList = map.get("id");
        Collection<Long> ageList = map.get("age");
        Set<String> tbSet = new HashSet<>();
        //定位到age字段值
        long age = Long.valueOf(String.valueOf(ageList.stream().findFirst().get()));
        //定位到id字段值
        long id = idList.stream().findFirst().get();
        //如果年齡大于100則說明是無效數(shù)據(jù),到user表查
        if (age > 100) {
            tbSet.add("user");
        } else {//反之基于id進(jìn)行取模運(yùn)算定位分表
            tbSet.add("user_" + id % 3);
        }
        return tbSet;

    }
}

4. 強(qiáng)制路由策略

強(qiáng)制路由算是比較少用的分片策略,它的分表算法由用戶自行實(shí)現(xiàn)且定位分表的邏輯與SQL語句沒有任何關(guān)系,常用于系統(tǒng)維度的分表算法,所以配置時只需給出分表實(shí)現(xiàn)的策略類即可:

spring.shardingsphere.sharding.tables.user.table-strategy.hint.algorithm-class-name=com.sharkChili.algorithm.TableHintShardingAlgorithm

可以看到分表實(shí)現(xiàn)策略如下:

  • 通過用戶入?yún)⒅蝎@取邏輯分表
  • 從入?yún)⒊霁@取邏輯分表對應(yīng)的value

基于上述兩個值組裝成分表:

public class TableHintShardingAlgorithm implements HintShardingAlgorithm<String> {


    @Override
    public Collection<String> doSharding(Collection<String> tableNames, HintShardingValue<String> hintShardingValue) {
        //定位傳入的邏輯分表
        String logicTableName = hintShardingValue.getLogicTableName();
        String logicTableValue = hintShardingValue.getValues().stream().findFirst().get();
        //基于values的第一個值定位分表號碼,并于邏輯分配構(gòu)成分表名稱
        String tbName = logicTableName+"_"+logicTableValue;
        return Arrays.asList(tbName);
    }
}

hint算法是通過外部指定分片信息讓分片策略決定路由最終指向,所以我們都是通過HintManager實(shí)例傳入組裝當(dāng)前線程的邏輯表名和值從而定位到分表:

HintManager hintManager = HintManager.getInstance();

        try {
            //邏輯分表傳入user,value傳入0,讓分表算法組成user_0
            hintManager.addTableShardingValue("user", 0L);
            List<User> userList = SpringUtil.getBean(UserMapper.class).selectByExample(null);
            log.info(JSONUtil.toJsonStr(userList));
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            //因?yàn)閔intManager是基于threadLocal進(jìn)行傳值,所以用完后注意手動clear清除線程數(shù)據(jù)
            hintManager.clear();
        }

從輸出結(jié)果就可以看出,我們通過傳參實(shí)現(xiàn)參數(shù)驅(qū)動式的分片算法是成功的:

5. 行表達(dá)式分片算法

最后還有一種行表達(dá)式的分片策略算法,只需給定id并在配置給定分片算法即可,使用于簡單的分表算法的實(shí)現(xiàn):

## 行表達(dá)式 使用哪一列用作計算分表策略,我們就使用id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
##具體的分表路由策略,我們有3個user表,使用主鍵id取余3,余數(shù)0/1/2分表對應(yīng)表user_0,user_2,user_2
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expressinotallow=user_$->{id % 3}

三、小結(jié)

本文結(jié)合源碼實(shí)現(xiàn)了解到sharding-jdbc自定義分表算法實(shí)現(xiàn)的拓展點(diǎn),并基于該拓展點(diǎn)完成我們的的號頭分表邏輯,希望對你有所幫助。

責(zé)任編輯:趙寧寧 來源: 寫代碼的SharkChili
相關(guān)推薦

2021-10-27 09:55:55

Sharding-Jd分庫分表Java

2023-07-24 09:00:00

數(shù)據(jù)庫MyCat

2020-11-06 15:30:23

分庫分表Sharding-JD數(shù)據(jù)庫

2025-04-03 08:35:00

分頁查詢開發(fā)代碼

2022-05-16 08:50:23

數(shù)據(jù)脫加密器

2022-06-22 07:32:53

Sharding分庫數(shù)據(jù)源

2024-03-14 09:30:04

數(shù)據(jù)庫中間件

2024-06-28 14:34:15

2023-03-13 07:35:44

MyBatis分庫分表

2023-11-03 09:17:12

數(shù)據(jù)庫配置庫表

2017-07-20 17:10:38

數(shù)據(jù)庫DB分庫sharding

2019-09-17 11:18:09

SQLMySQLJava

2022-12-09 09:21:10

分庫分表算法

2020-07-30 17:59:34

分庫分表SQL數(shù)據(jù)庫

2019-11-12 09:54:20

分庫分表數(shù)據(jù)

2021-08-31 20:21:11

VitessMySQL分庫

2023-08-11 08:59:49

分庫分表數(shù)據(jù)數(shù)據(jù)庫

2024-06-26 00:34:12

2020-11-18 09:39:02

MySQL數(shù)據(jù)庫SQL

2010-10-15 16:03:03

Mysql分表處理
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

91嫩草亚洲精品| 亚洲成人高清| 久久久精品一品道一区| 国产精品自拍小视频| 中文字幕av播放| 凹凸成人在线| 一本久久综合亚洲鲁鲁五月天| 日本一区二区三区视频在线观看| 国产露脸国语对白在线| 国产一区二区三区的电影 | 欧美日韩中国免费专区在线看| 欧美日韩综合久久| 99热这里精品| 久久av最新网址| 色综合男人天堂| 青青青视频在线免费观看| 久久99精品国产自在现线| 欧美色综合网站| 国产 日韩 亚洲 欧美| 欧美三级黄网| 久久蜜桃av一区精品变态类天堂 | 97国产精品视频人人做人人爱| 天堂久久精品忘忧草| 一区二区三区欧洲区| 欧美无砖专区一中文字| 春日野结衣av| 国产www视频在线观看| 国产精品无遮挡| 久久伊人资源站| 人妻偷人精品一区二区三区| 国产综合色在线视频区| 国产精品wwwwww| 伊人久久综合视频| 欧美 日韩 国产 一区| 最近2019中文字幕第三页视频| 91精品小视频| av综合网站| 日韩视频一区二区三区在线播放| 2025韩国理伦片在线观看| 92国产精品| 婷婷中文字幕一区三区| 无码人妻精品一区二区蜜桃网站| 免费看a在线观看| 国产日韩精品一区二区三区| 欧美不卡1区2区3区| 香蕉视频网站在线| 99re6这里只有精品视频在线观看| 1区1区3区4区产品乱码芒果精品| 7777久久亚洲中文字幕| 日本免费新一区视频| 日韩av男人的天堂| 亚洲大片免费观看| 天堂av在线一区| 国产91九色视频| 天堂免费在线视频| 男女性色大片免费观看一区二区| 日韩av片电影专区| 国产第一页在线观看| 日韩高清不卡在线| 国产精品网红直播| 国产精品毛片一区二区在线看舒淇 | 波多野结衣的一区二区三区 | 无码人妻aⅴ一区二区三区玉蒲团| 色噜噜成人av在线| 91精品国产综合久久久久久漫画| 91香蕉国产线在线观看| 亚洲一区电影| 亚洲国产成人精品女人久久久 | 99热这里只有精品5| 国产乱子伦视频一区二区三区| 亚洲一区二区三区xxx视频| 国产精品呻吟久久| 成人免费高清视频在线观看| 久久久久久高清| 成人在线免费看| 国产精品久久久久久久第一福利| 日韩不卡一二区| 久久www人成免费看片中文| 亚洲成人综合视频| www.超碰com| 国产精品一区二区三区www| 精品捆绑美女sm三区| 亚洲国产果冻传媒av在线观看| 国产欧美日韩精品一区二区免费| 最近2019中文字幕在线高清| 中文字幕在线观看成人| 亚洲日本免费| 国产精品亚洲激情| 亚洲乱色熟女一区二区三区| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 成人免费福利| 欧美精选在线播放| 国产精品久久久久久亚洲色| 精品国产网站| 欧美人在线视频| 香蕉污视频在线观看| 麻豆国产精品一区二区三区| 成人av片网址| 懂色一区二区三区| 亚洲国产成人91porn| 精品999在线| 成人爽a毛片| 这里只有精品在线播放| 国产精品美女毛片真酒店| 美女性感视频久久| 九色视频成人porny| 日本a在线播放| 狠狠躁18三区二区一区| 97超碰人人看| 欧美大片aaaa| 欧美在线激情网| www.久久成人| 国产精品丝袜久久久久久app| 丁香婷婷综合激情| 欧美成人三级| 亚洲片在线资源| 国产第一页第二页| 老司机免费视频一区二区| 激情小说综合区| 污视频网站免费在线观看| 欧美综合亚洲图片综合区| 亚洲天堂av网站| 97视频在线观看网站| 青青草成人影院| 九九精品在线视频| ,一级淫片a看免费| 国产日韩亚洲欧美综合| 女人和拘做爰正片视频| 18国产精品| 久久久国产视频| 无码人妻精品一区二区| www.日韩精品| www.亚洲视频.com| 韩国三级成人在线| 久久婷婷国产麻豆91天堂| 一区二区三区麻豆| 国产婷婷色一区二区三区四区| 奇米精品一区二区三区| 粉嫩av一区二区| 欧美黑人视频一区| 成人av一区二区三区在线观看| 亚洲欧洲综合另类在线| 亚洲午夜精品一区| 91麻豆国产自产在线观看亚洲| 国产精品久久精品| 91电影在线播放| 欧美亚洲国产一区二区三区| 老熟妇一区二区| 日韩专区欧美专区| 日韩欧美一区二区三区久久婷婷| 欧美黑人粗大| 亚洲一区二区久久| 在线观看国产区| 国产精品美女久久久久久久久| 成人午夜激情av| 成人vr资源| 国产日本欧美视频| 麻豆系列在线观看| 日韩欧美高清一区| 国产一级视频在线观看| 99久久99久久精品免费观看| 日日鲁鲁鲁夜夜爽爽狠狠视频97| 最新国产一区| 国产精品中文在线| 国产高清一区二区三区视频 | 亚州精品天堂中文字幕| 婷婷五月综合久久中文字幕| 色综合天天综合网天天看片| 亚洲成人黄色av| 久久激情综合网| 97超碰在线视| 日本亚洲不卡| 国产精品偷伦一区二区 | 2019av中文字幕| 青青操视频在线| 欧美三级电影在线看| 精品自拍偷拍视频| av在线不卡网| 欧美性猛交xxx乱久交| 99久久综合狠狠综合久久aⅴ| av噜噜色噜噜久久| 三级成人黄色影院| 久久久999精品视频| 日韩中文字幕观看| 欧美日韩中文精品| 久久免费公开视频| 国产婷婷一区二区| 男人女人拔萝卜视频| 亚洲综合社区| 老司机av福利| 欧美网色网址| 91久久久久久久久久| 天堂中文在线播放| 美女性感视频久久久| 免费成人av电影| 欧美一卡二卡在线观看| 波多野结衣视频网站| 亚洲视频网在线直播| 国产精品久久久久久在线观看| 男女男精品视频| 妞干网在线观看视频| 欧美激情理论| 欧洲亚洲一区| 成人影院中文字幕| 国产一区二区香蕉| 午夜精品久久久久久久久久蜜桃| 色综合久久久久久中文网| 福利视频在线导航| 日韩第一页在线| hs视频在线观看| 在线观看亚洲a| 日韩欧美一区二区一幕| 亚洲欧美偷拍卡通变态| 日本污视频网站| 91一区二区三区在线观看| 手机免费看av网站| 日韩国产高清在线| 777久久久精品一区二区三区| 一区二区影视| 一本一道久久a久久精品综合| 亚洲图区在线| 极品校花啪啪激情久久| 91午夜精品| 91麻豆国产语对白在线观看| 免费在线成人激情电影| 欧美诱惑福利视频| 男人天堂视频在线观看| 久久久亚洲天堂| 午夜伦理在线视频| 久久艹在线视频| 好了av在线| 久久久精品电影| 日本免费中文字幕在线| 伊人久久男人天堂| 国产一区二区影视| 亚洲偷熟乱区亚洲香蕉av| 三级视频在线| 国产午夜精品理论片a级探花| 人妻精品一区二区三区| 亚洲第一av网| 天天爽夜夜爽夜夜爽| 亚洲国产小视频| 人妻丰满熟妇av无码区hd| 亚洲精品久久久久中文字幕欢迎你| 国产成人精品免费看视频| 欧美一区二区三区四区五区| 国产毛片久久久久| 欧美一区二区三区男人的天堂| 国产美女明星三级做爰| 日韩欧美国产精品| 黄色福利在线观看| 日韩av网址在线| 青青九九免费视频在线| 亚洲最新中文字幕| 91欧美在线视频| 超碰日本道色综合久久综合| av黄色在线| 午夜精品久久久久久99热| 日本免费一区二区六区| 国产精品99导航| 欧美男女视频| 粉嫩av免费一区二区三区| 美女主播精品视频一二三四| 免费精品视频一区二区三区| 国产91一区| 一本久久a久久精品vr综合| 91精品啪在线观看国产81旧版| 热久久最新网址| 99热在线精品观看| 99视频精品免费| 久久99精品一区二区三区三区| 日本亚洲一区二区三区| 99re这里都是精品| 特级西西人体高清大胆| 亚洲一区在线看| 在线观看免费av片| 欧美欧美午夜aⅴ在线观看| 精品人妻aV中文字幕乱码色欲| 日韩国产欧美精品一区二区三区| av男人的天堂在线| 色综合久久久久久中文网| 桃色一区二区| 亚洲r级在线观看| 久操成人av| 特色特色大片在线| 亚洲一区二区网站| 日韩av片免费观看| 99re热这里只有精品视频| 四虎成人免费影院| 无码av免费一区二区三区试看| 成人午夜精品视频| 精品999在线播放| www.在线播放| 97香蕉久久夜色精品国产| 福利一区和二区| 国产伦精品一区二区三区四区免费 | 日韩电影免费在线看| 国产精品区在线| 成人激情文学综合网| 人妻无码一区二区三区免费| 午夜影院久久久| 中文字幕在线网站| 精品国产乱码久久| 嫩草香蕉在线91一二三区| 欧美亚洲国产日韩2020| 亚洲精品黑牛一区二区三区| 日本视频一区二区不卡| 激情久久久久| 古装做爰无遮挡三级聊斋艳谭| 久久久久久久久久看片| 国产亚洲色婷婷久久99精品| 欧美福利电影网| 国产在线91| 97视频在线看| 一区二区三区四区高清视频| 亚洲国产欧美一区二区三区不卡| 在线亚洲成人| 国产不卡一二三| 一级特黄大欧美久久久| 国产伦精品一区二区三区四区 | 欧美少妇精品| 国产精品亚洲综合| 伊人成综合网| 欧美一级特黄aaa| 国产精品免费久久久久| av片免费观看| 亚洲欧美精品中文字幕在线| 免费v片在线观看| 国产综合精品一区二区三区| 亚洲天堂久久| www.黄色网| 亚洲精品免费在线| 国产情侣自拍小视频| 久久精品视频网站| 国产成年精品| 国产免费xxx| 国产一区美女在线| 朝桐光av在线| 欧美一级一级性生活免费录像| 色网站在线看| 成人黄色av免费在线观看| 欧美大人香蕉在线| 久久精品国产露脸对白| 亚洲欧美偷拍三级| 国产成人a人亚洲精品无码| 久久av.com| 999久久久精品一区二区| 日本一本中文字幕| 99免费精品在线观看| www成人在线| 亚洲人成电影网站色www| 日本免费一区二区三区四区| 亚洲高清视频一区| 久久福利资源站| 欧美精品久久久久性色| 欧美精品一区二| 亚洲优女在线| 日韩久久久久久久| 美女www一区二区| 亚洲二区在线播放| 日韩你懂的在线播放| 激情黄产视频在线免费观看| 欧美日韩在线观看一区二区三区| 日韩中文字幕区一区有砖一区 | 久草免费资源站| 午夜精品123| 可以在线观看的黄色| 国产日韩在线观看av| 欧美激情第二页| 性色av蜜臀av浪潮av老女人| 色综合天天综合网天天狠天天| 91亚洲欧美| 成人综合电影| 欧美中文字幕| 女人18毛片毛片毛片毛片区二| 日韩精品一区二区三区在线| 国产美女精品写真福利视频| 日韩精品一区二区三区四区五区| 激情综合一区二区三区| 国产无遮挡免费视频| 中文字幕日韩av综合精品| 亚洲性视频在线| 无码人妻精品一区二区三区66| 亚洲精品免费在线播放| 欧美zozo| 91九色露脸| 欧美aaa在线| 久久久久99精品| 这里只有精品视频在线| a看欧美黄色女同性恋| 69久久久久久| 亚洲高清免费观看高清完整版在线观看| 国产粉嫩一区二区三区在线观看| 999视频在线免费观看| 久久亚洲影院| 久久午夜鲁丝片午夜精品| 一区二区欧美在线| 精品丝袜久久| 99九九99九九九99九他书对| 日韩欧美一区二区三区|