- 要坚信 在一个html文件中 , 可以设置它所包含的 "子文件"中 的元素的样式, 这是可以的,是有效的, 而且也只能这样设置!
比如在a.html中, 可能设置了layout, layout中有tab的href是另外的b.html文件, 这样的话, b.html文件就是包含在 a.html文件中了.
- 通常在 b.html文件中, 就是直接写body内容了, 不会再 设置style样式了, 而且在b.html中设置样式style标签也无效! 所以只能在a.html文件中写style
- 为什么写table>tr>th样式无效??
本来在a.html源文件中, 就是明明白白的 写的<table><tr><th>.....</th> , <td>...</td>
, tr td/th就是 table的直接 子元素, 为什么设置的样式却无效呢?
原来, 虽然在你的源文件中确实是这样写的, 但是在浏览器渲染后的代码中, 你可以看到table标签后, 又增加了一个新的标签元素<tbody>
这个是浏览器添加的, 但是浏览器生效/解释
执行的,却是按浏览器渲染后的代码来的, 所以实际执行的代码就是<table> <tbody> <tr> <th>/<td>
了. 所以你写的 table>tr>th/td 自然也就无效了!
因为这里的tr 已经不是table的 直接子元素了!这里出问题的就是 这个浏览器自己 新增的tbody标签了.
- 要明白: 实际上你的 源文件和 浏览器渲染后的html文件(也就是你在firebug中看到的内容) 往往是有差异的, 而且差异往往是较大的!
- 因为渲染后的文件包括了 style, 和js等事件添加的代码! 甚至添加的一些新元素.(相当于要展开你的源代码, 对你的源代码进行增加) 而且是常见的现象.
- 最重要的是, 浏览器生效的/起效的, 是按 浏览器渲染后的代码 来解释执行的, 而不是按你的源代码来执行的
- 所以, 这个table tr th/td是比较特殊的, 以后就记得在写 th/td的样式 的时候, 就不要写 大于符号> 了, 而是直接写: table th, 或 table td了.
========================================================
行内元素,比如span等, 可以设置 margin-left/right, 和 padding-left/right, 但是不能设置margin和padding的竖直方向的属性, 比如margin-top/bottom, padding-top/bottom, 它们的设置是无效的, 但是img元素是例外, 它的padding和margin的水平方向和竖直方向上的值都有效. 而块级元素比如p/div等 的margin和padding在水平和竖直方向上都是有效的!
理解mysql的子查询?
- mysql和mycli的区别, 前者不能直接输入password, 直接输入-p参数会报错, 而后者使用-p 时必须直接输入密码, 不输入密码反而会报错
mycli -ufoo -p 123
而mysql -uroot -p
- 如果向表中插入数据, 如果手动插入, 则要用values子句, 必须写values, 而如果用其他select查询结果来插入, 就不要写values, 直接写select子句就行:
insert into tbl_name select * from tbl_2
- 子查询包括三种: where子查询, from子查询, exists子查询
where子查询是将where内层的查询结果作为where的条件表达式中使用, 通常这个子查询是获得max, average, min, group by等的结果, where子句中可以使用的运算符有 各种都可以, 包括=, >= , in , not in, between等都可以.
而from子句, 是因为 查询结果集本身也可以作为表来看, 所以可以使用子查询在from子句中, 通常要把 from子查询 重命名为tmp临时表来使用...
exists子句, 则是将外层语句中的 字段值 传入到内层exists查询子句中, 来判断内层子句的条件是否为真: 如果exists(子查询)中的 子查询返回的结果集为空, 就等于说: 不存在那样的查询结果, 那么where条件表达式就为false, 反之, 如果exists子查询返回的结果集不为空, 就说明 确实存在..., 就说明where条件为真.
mysql数据表模型?
-
字段就是变量, 每条记录的字段值可能不同;
-
where就是条件表达式,
-
中间(内层)查询出来的结果集可以作为二维表,再被查询(作为子查询)
如何选出结果集, 选出结果集的步骤是: mysql引擎 一条记录一条记录地扫描, (一行一行的扫描), 相当于for/while循环..., 然后判断where条件, 如果为true, 就选出这条记录的相应字段值,如果where条件为false, 就跳过这一行, 不选字段值, 然后接着扫描下一行, 直到最后一行扫描完.
所以 select子句是最后执行的: 因为要先 执行其他子句, 准备好扫描结果集, 最后才选出所需要的字段值.
理解表模型和mysql如何选出最后记录结果的 过程很重要, 特别是for/whie循环的思想, 这样就可以一条记录一条记录来分析最后得到的产生的结果. -
所以, 如果select字段集合中, 表中存在的字段, 就取当前行的相应字段值, 表中没有的字段, 就求出这个"常数"或"变量表达式"的值, 然后它们合起来作为最后结果中的一行, 依次类推
-
但是, 如果有distinct关键字, 那么它作用的范围还是 select的 所有字段, 不管是表中存在的字段, 和表中没有的字段, 都包括在内, 是所有的select字段的值都不相同的记录才选出到最后的结果集中.事实上, 最后执行 的是distinct子句. 把表A 从where过滤 -> group by过滤 ->having 过滤, 最后选出select的字段集-> 最后经disctinct过滤获得.
-
所以, 通常distinct主要是用在 单一字段的选择语句中, 如果有多个字段需要选出而又要达到 distinct的效果, 那么还是用 group by分组比较好!
-
所以, 比如:
select f1, f2,... from A left join B on A.Af1=B.Bf1 where B.Bf1 is null
的执行顺序就是: 先要让A 表和B 表根据 A.Af1=B.Bf1连接查询出来得到的结果集, 经where条件过滤, 再得到结果集, 最后才从这个结果集中选出f1, f2等字段值.
总之, 在复杂业务逻辑的查询语句中, 方法是: 先写出基本的查向子句, 再准备好各种 where/from/exists/join等 查询子句, 最后将它们组装 /组合/装配起来即可.
- count函数, 是统计一个表中满足条件的记录的条数. 有几种写法: count(), count(1), count(field_name)
其执行过程是: 扫描表的每一行,满足条件的行,就累加1,否则就不加; 然后扫描下一行, ...
count(field_name)是按某个字段来统计条数, 注意它不统计字段值为null的行数, 所以通常不要采取这种写法
count(1)是假设/把它看作是: 表中有一个"常数"字段,来扫描统计, 当然就是每一行都会累加的. 这个写法还可以是 其他的"常数字段", 比如: count(2), count(3), count('x'), count('a')...
count() 会把这个* 翻译成"主键"字段, 然后扫描统计累加.
通常count(1)效率最高, 其次是count(), 最后是count(field_Name).
据说, mysql对count(1), count()做了优化? 所谓的优化 就是mysql内部事先保存了一个变量,来保存记录条数, 查询时,就不用扫描, 直接给出预存变量的值??
==================================================
从一个表中选出 字段值不在另一个表中的 字段
参考: https://blog.csdn.net/zuihongyan518/article/details/80936604
它说有三种方法:
- select distinct A.id from A where A.id not in (select id from B);
- select A.id from A left join B on A.id=B.id where B.id is null;
- select * from A where (select count(1) from B where A.id=B.id)=0
mysql的where中多个条件的连接?
- 多个条件的连接有 and 和 or, 不是 && 和 ||
- and: 是所有条件都满足的 记录才会被选出来, 而 or是 其中只要有一个条件满足的行 都会被选出来, 反之...
- 优先级: 首先是 括号的优先级最高, 其次, 如果没有小括号, 那么 and的优先级比 or的优先级更高, 比如: ... where condition_A or condition_B and conditon_C 那么就是先判断 condition_B and C, 最后才判断 B and C 的结果 跟 A 的 或运算