MySQL 中视图有啥作用,啥时候有需要用到,能够提供一些学习的网站或者资料?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 中视图有啥作用,啥时候有需要用到,能够提供一些学习的网站或者资料?相关的知识,希望对你有一定的参考价值。
mysql 中视图有什么作用,什么时候有需要用到,能够提供一些学习的网站么?
视图又叫虚表。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。视图主要有以下作用:
1、安全。一些数据表有着重要的信息。有些字段是保密的,不能让用户直接看到。这时就可以创建一个视图,在这张视图中只保留一部分字段。这样,用户就可以查询自己需要的字段,不能查看保密的字段。
2、性能。关系数据库的数据常常会分表存储,使用外键建立这些表的之间关系。这时,数据库查询通常会用到连接(JOIN)。这样做不但麻烦,效率相对也比较低。如果建立一个视图,将相关的表和字段组合在一起,就可以避免使用JOIN查询数据。
3、灵活。如果系统中有一张旧的表,这张表由于设计的问题,即将被废弃。然而,很多应用都是基于这张表,不易修改。这时就可以建立一张视图,视图中的数据直接映射到新建的表。这样,就可以少做很多改动,也达到了升级数据表的目的。
关于视图的学习,我建议你参考mysql手册。在网上找一些示例,很快就入门了。 参考技术A 最简单来说就是把多张表虚拟成一张表,这样在你查询数据的时候,直接查询这张虚拟表就行了,不用再联合查询多张表了。 参考技术B
MySQL 8.0 推出了histogram,也叫柱状图或者直方图。先来解释下什么叫直方图。
关于直方图
我们知道,在DB中,优化器负责将SQL转换为很多个不同的执行计划,完了从中选择一个最优的来实际执行。但是有时候优化器选择的最终计划有可能随着DB环境的变化不是最优的,这就导致了查询性能不是很好。比如,优化器无法准确的知道每张表的实际行数以及参与过滤条件的列有多少个不同的值。那其实有时候有人就说了,索引不是可以解决这个问题吗?是的,不同类型的索引可以解决这个问题,但是你不能每个列都建索引吧?如果一张表有1000个字段,那全字段索引将会拖死对这张表的写入。而此时,直方图就是相对来说,开销较小的方法。
直方图就是在 MySQL 中为某张表的某些字段提供了一种数值分布的统计信息。比如字段NULL的个数,每个不同值出现的百分比、最大值、最小值等等。如果我们用过了 MySQL 的分析型引擎brighthouse,那对这个概念太熟悉了。
MySQL的直方图有两种,等宽直方图和等高直方图。等宽直方图每个桶(bucket)保存一个值以及这个值累积频率;等高直方图每个桶需要保存不同值的个数,上下限以及累计频率等。MySQL会自动分配用哪种类型的直方图,我们无需参与。
MySQL 定义了一张meta表column_statistics 来存储直方图的定义,每行记录对应一个字段的直方图,以json保存。同时,新增了一个参数histogram_generation_max_mem_size来配置建立直方图内存大小。
不过直方图有以下限制:
1. 不支持几何类型以及json。2. 不支持加密表和临时表。3. 不支持列值完全唯一。4. 需要手工的进行键值分布。
那我们来举个简单的例子说明直方图对查询的效果提升。
举例
表相关定义以及行数信息等:
mysql> show create table t2\\G
*************************** 1. row ***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`rank1` int(11) DEFAULT NULL,
`rank2` int(11) DEFAULT NULL,
`rank3` int(11) DEFAULT NULL,
`log_date` date DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_rank1` (`rank1`),
KEY `idx_log_date` (`log_date`)
) ENGINE=InnoDB AUTO_INCREMENT=49140 DEFAULT CHARSET=utf8mb4 \\
COLLATE=utf8mb4_0900_ai_ci STATS_PERSISTENT=1 STATS_AUTO_RECALC=0
1 row in set (0.00 sec)
mysql> select count(*) from t2;
+----------+
| count(*) |
+----------+
| 30940 |
+----------+
1 row in set (0.00 sec)
同时对t2克隆了一张表t3
mysql> create table t3 like t2;
Query OK, 0 rows affected (0.13 sec)
mysql> insert into t3 select * from t2;
Query OK, 30940 rows affected (1.94 sec)
Records: 30940 Duplicates: 0 Warnings: 0
给表t3列rank1和log_date 添加histogram
mysql> analyze table t3 update histogram on rank1,log_date;+--------+-----------+----------+-----------------------------------------------------+| Table | Op | Msg_type | Msg_text |+--------+-----------+----------+-----------------------------------------------------+| ytt.t3 | histogram | status | Histogram statistics created for column 'log_date'. || ytt.t3 | histogram | status | Histogram statistics created for column 'rank1'. |+--------+-----------+----------+-----------------------------------------------------+2 rows in set (0.19 sec)
我们来看看histogram的分布状况
mysql> select json_pretty(histogram) result from information_schema.column_statistics where table_name = 't3' and column_name = 'log_date'\\G*************************** 1. row ***************************result: "buckets": [ [ "2018-04-17", "2018-04-20", 0.01050420168067227, 4 ], ... , [ "2019-04-14", "2019-04-16", 1.0, 3 ] ], "data-type": "date", "null-values": 0.0, "collation-id": 8, "last-updated": "2019-04-17 03:43:01.910185", "sampling-rate": 1.0, "histogram-type": "equi-height", "number-of-buckets-specified": 1001 row in set (0.03 sec)
MySQL自动为这个字段分配了等高直方图,默认为100个桶。SQL A:
select count(*) from t2/t3 where (rank1 between 1 and 10) and log_date < '2018-09-01';
SQL A的执行结果:
mysql> select count(*) from t2/t3 where (rank1 between 1 and 10) and log_date < '2018-09-01';+----------+| count(*) |+----------+| 2269 |+----------+1 row in set (0.01 sec)
无histogram的执行计划
mysql> explain format=json select count(*) from t2 where (rank1 between 1 and 10) and log_date < '2018-09-01'\\G*************************** 1. row ***************************EXPLAIN: "query_block": "select_id": 1, "cost_info": "query_cost": "2796.11" , "table": "table_name": "t2", "access_type": "range", "possible_keys": [ "idx_rank1", "idx_log_date" ], "key": "idx_rank1", "used_key_parts": [ "rank1" ], "key_length": "5", "rows_examined_per_scan": 6213, "rows_produced_per_join": 3106, "filtered": "50.00", "index_condition": "(`ytt`.`t2`.`rank1` between 1 and 10)", "cost_info": "read_cost": "2485.46", "eval_cost": "310.65", "prefix_cost": "2796.11", "data_read_per_join": "72K" , "used_columns": [ "rank1", "log_date" ], "attached_condition": "(`ytt`.`t2`.`log_date` < '2018-09-01')"
有histogram的执行计划
mysql> explain format=json select count(*) from t3 where (rank1 between 1 and 10) and log_date < '2018-09-01'\\G*************************** 1. row ***************************EXPLAIN: "query_block": "select_id": 1, "cost_info": "query_cost": "0.71" , "table": "table_name": "t3", "access_type": "range", "possible_keys": [ "idx_rank1", "idx_log_date" ], "key": "idx_log_date", "used_key_parts": [ "log_date" ], "key_length": "4", "rows_examined_per_scan": 1, "rows_produced_per_join": 1, "filtered": "100.00", "index_condition": "(`ytt`.`t3`.`log_date` < '2018-09-01')", "cost_info": "read_cost": "0.61", "eval_cost": "0.10", "prefix_cost": "0.71", "data_read_per_join": "24" , "used_columns": [ "rank1", "log_date" ], "attached_condition": "(`ytt`.`t3`.`rank1` between 1 and 10)" 1 row in set, 1 warning (0.00 sec)
我们看到两个执行计划的对比,有Histogram的执行计划cost比普通的sql快了好多倍。上面文字可以看起来比较晦涩,贴上两张图,看起来就很简单了。我这里举得例子相对简单,有兴趣的朋友可以更深入学习其他复杂些的例子。
removeAllViews() 对子视图有啥作用?
【中文标题】removeAllViews() 对子视图有啥作用?【英文标题】:What does removeAllViews() do with child views?removeAllViews() 对子视图有什么作用? 【发布时间】:2015-04-28 17:24:42 【问题描述】:我的布局中有以下层次结构:
ScrollView
RadioGroup
RelativeLayout
RadioButton
ImageView
RelativeLayout
RadioButton
ImageView
...
现在的重点是,它在 RadioButtons
和 ImageViews
定义了默认值(占位符)的 XML 编辑器中看起来很好,但是当我启动一个活动并在 RadioGroup
上调用 removeAllViews()
时,所有ImageViews
消失。有趣的是,所有按钮都有新的值,只有ImageViews
无论如何都不会更新(设置新的源图像没有结果)。
所以,我的问题是:removeAllViews()
是完全擦除子视图(就像它们从未存在于布局 XML 文件中一样)还是只是删除了一些值,留下要定义的视图参数(例如设置新的源图像或新的按钮说明)?
【问题讨论】:
【参考方案1】:来自official documentation,removeAllViews()
:
调用此方法从 ViewGroup 中删除所有子视图。
调用此方法会将所有子视图设置为null
,因此它将从自身中删除子视图,并且该子视图变为无效(或不被视为子视图),但不是就像它从未存在于 XML 文件中一样。
这是removeAllViews() code:
public void removeAllViews()
removeAllViewsInLayout();
requestLayout();
invalidate();
正如您在removeAllViewsInLayout() 方法中看到的,它将子值设置为null:
children[i] = null;
【讨论】:
好的,这说明了一点。那么让子视图可用和可用的相反顺序是什么? 我认为removeAllViews();
没有反作用,您可以使用addView();
再次将您的视图添加到 ViewGroup。以上是关于MySQL 中视图有啥作用,啥时候有需要用到,能够提供一些学习的网站或者资料?的主要内容,如果未能解决你的问题,请参考以下文章