2017年07月24日 10:01:07
阅读数:694
在表设计过程中,我无意中觉得一对一关系觉得好没道理,直接放到一张表中不就可以了吗?真是说,网上信息什么都有,也可以说与我一样困惑的有好多人。感谢大神在网上的活跃,我知道了一对一关系存在的必要性。
1.首先就是这种关系出现的场景是什么样子,最好可以举个实际中的需求。
这样的场景有很多,比如:就拿最普通的用户信息来说,数据库中有一个表为user,一个表为user_auth.user表主要存放的字段为用户基本的信息(用户ID、真实姓名、昵称、真实头像、性别、职位、教育程度、专业、创建该用户的时间等),而在user_auth为验证表(用户ID、用户密码、邮箱、手机号等)。当涉及到一个具体实体的信息量较多,或者可以分类的时候,就可以使用了1-1,当然只要你能把一个实体的关系拆分成几个有归类的部分也可以适用。
2.为什么要使用两个表来维护一对一关系,为什么不直接将两个表中的字段全都放在一张表里来展示?
如果都放在一张表里,一:不便于管理(包括查询执行速度),二:也就达不到关系型数据库的特性。三:可更好对业务进行事务隔离操作
3.提出这种关系的目的是什么,就是为提高我们数据库查询条件吗?
目的:为第二问答案。这与数据库查询条件没有必然的说法。你说查询速度或者为了方便区分查询管理还说得过去。
还有
-
公司和公司地址,总经理和公司,部门经理和部门 都是一对一
-
对于小字段小数据量的数据库来说,放到一起无所谓了,但是对于大字段的数据库,要添加删除修改某一个字段,由于数据库大,字段多,数据库找到这个字段耗时久,造成锁表等问题。同时分离存储大数据的表时,查询也会节省时间,因为某些框架会映射表里面所有的字段,存在一起查询时会把不需要的字段也映射进来造成耗时过久。还有,大数据量的表分离存储对于索引创建,读写分离,分割等操作都有优势。
-
同2
我觉得这两种答案比较好。COPY在这里,记得时常看看,记在心里。
数据库一对一、一对多、多对多设计
2016年11月18日 10:21:03
阅读数:20859
做一个项目,必然是少不了数据库设计的!在学习阶段,基本都是单表。然而在实际开发过程中,一对多,多对多的表处处都是!简单整理一下,一对多,多对多表如何设计整理一下思路:
数据库实体间有三种对应关系:一对一,一对多,多对多。
一对一关系示例:
-
-
- 一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号。
一对多关系示例:
多对多关系示例:
1.一对多关系处理:
通过学生和班级问题了解一对多:
设计数据库表:只需在 学生表 中多添加一个班级号的ID;
注:在数据库中表中初学时,还是通过添加主外键约束,避免删除数据时造成数据混乱!
2.多对多关系处理:
通过学生选课了解多对多问题的处理:
在多对多中在一个表中添加一个字段就行不通了,所以处理多对多表问题时,就要考虑建立关系表了
例:
学生表: 课程表: 关系表:
注:所以对于多对多表,通过关系表就建立起了两张表的联系!多对多表时建立主外键后,要先删除约束表内容再删除主表内容
-
你让工人为你工作7天,给工人的回报是一根金条。金条平分成相连的7段,你必须在每天结束时给他们一段金条,如果只许你两次把金条弄断,你如何给你的工人付费? 答案:第一天给1段,第二天让工人把1段归还后再给他给2段,第三天给1段,第四天让工人归还1、2段,给4段。第五天依次类推……
-
请把一盒蛋糕切成8份,分给8个人,但蛋糕盒里还必须留有一份。 答案:面对这样的怪题,有些应聘者绞尽脑汁也无法分成;而有些应聘者却感到此题实际很简单,把切成的8份蛋糕先拿出7份分给7人,剩下的1份连蛋糕盒一起分给第8个人。
-
小明一家过一座桥,过桥时是黑夜,所以必须有灯。现在小明过桥要1秒,小明的弟弟要3秒,小明的爸爸要6秒,小明的妈妈要8秒,小明的爷爷要12秒。每次此桥最多可过两人,而过桥的速度依过桥最慢者而定,而且灯在点燃后30秒就会熄灭。问:小明一家如何过桥? 答案:这类智力题目,其实是考察应聘者在限制条件下解决问题的能力。具体到这道题目来说,很多人往往认为应该由小明持灯来来去去,这样最节省时间,但最后却怎么也凑不出解决方案。但是换个思路,我们根据具体情况来决定谁持灯来去,只要稍稍做些变动即可:第一步,小明与弟弟过桥,小明回来,耗时4秒;第二步,小明与爸爸过河,弟弟回来,耗时9秒;第三步,妈妈与爷爷过河,小明回来,耗时13秒;最后,小明与弟弟过河(不用回来了),耗时3秒,总共耗时29秒。
-
一群人开舞会,每人头上都戴着一顶帽子。帽子只有黑白两种,黑的至少有一顶。每个人都能看到其他人帽子的颜色,却看不到自己的。主持人先让大家看看别人头上戴的是什么帽子,然后关灯,如果有人认为自己戴的是黑帽子,就打自己一个耳光。第一次关灯,没有声音。于是再开灯,大家再看一遍,关灯时仍然鸦雀无声。一直到第三次关灯,才有劈劈啪啪打耳光的声音响起。问有多少人戴着黑帽子? 答案:假如只有一个人戴黑帽子,那他看到所有人都戴白帽,在第一次关灯时就应自打耳光,所以应该不止一个人戴黑帽子;如果有两顶黑帽子,第一次两人都只看到对方头上的黑帽子,不敢确定自己的颜色,但到第二次关灯,这两人应该明白,如果自己戴着白帽,那对方早在上一次就应打耳光了,因此自己戴的也是黑帽子,于是也会有耳光声响起;可事实是第三次才响起了耳光声,说明全场不止两顶黑帽,依此类推,应该是关了几次灯,有几顶黑帽。
-
一楼到十楼的每层电梯门口都放着一颗钻石,钻石大小不一。你乘坐电梯从一楼到十楼,每层楼电梯门都会打开一次,只能拿一次钻石,问怎样才能拿到最大的一颗? 答案:这是一道没有标准答案的试题,实际上它考的是你的开放性思维和逻辑推理能力. 第一步:对1到3层的大小进行比较,记住最大的一颗。 第二步:4到6层作为参考,将4-6层的最大的跟1-3层的最大的作比较,确认最大的一个的平均水平。 第三步:在最后4层中选择一个属于最大一批的,如果第7层的就是最大的平均水平的,那就闭上眼睛不再观察之后的。这就是最大的一颗。
-
烧一根不均匀的绳要用一个小时,如何用它来判断半个小时? 答案:两边一起烧。
-
为什么下水道的盖子是圆的? 答案之一:从麻省理工大学一位计算机系教授那里听来的答案,首先在同等用材的情况下他的面积最大。第二因为如果是方的、长方的或椭圆的,那无聊之徒拎起来它就可以直接扔进地下道啦!但圆形的盖子嘛,就可以避免这种情况了
-
有7克、2克砝码各一个,天平一只,如何只用这些物品三次将140克的盐分成50、90克各一份? 答案:(1)用天平把140g分成两等份,每份70g; (2)用天平把其中一份70g分成两等份,每份35g; (3)取其中一份35g放到天平的一端,把7g的砝码也放到这一端,再把2g的砝码放到天平的另一端.从7g砝码一端移取盐到2g砝码的一端,直到天平平衡.这时,2g砝码一端盐的量为20g.把这20g和已开始分出的未动一份70g盐放在一起,就是90g,其他的盐放在一起,就是50g.
-
想象你在镜子前,请问,为什么镜子中的影像可以颠倒左右,却不能颠倒上下? 答案:因为人的两眼在水平方向上对称。
-
你有两个罐子,50个红色弹球,50个蓝色弹球,随机选出一个罐子,随机选取出一个弹球放入罐子,怎么给红色弹球最大的选中机会?在你的计划中,得到红球的准确几率是多少? 答案:一个罐子放一个红球,另一个罐子放49个红球和50个蓝球,概率接近75%. 这是所能达到的最大概率了。 实际上,只要一个罐子放<50个红球,不放篮球,另一个罐子放剩下的球,拿出红球的概率就大于50%。
-
你有四人装药丸的罐子,每个药丸都有一定的重量,被污染的药丸是没被污染的重量+1.只称量一次,如何判断哪个罐子的药被污染了? 答案:先假设每颗药丸重x克,然后每个罐取分别标上1,2,3,4号.一号取一颗药丸,二号取两颗药丸,是几号就取几颗,一起称,如果是一号被污染质量为(10x+1),二号被污染质量为(10x+2),依此类推.
-
对一批编号为1~100 全部开关朝上开的灯进行以下操作凡是1 的倍数反方向拨一次开关2 的倍数反方向又拨一次开关3 的倍数反方向又拨一次开关。问最后为关熄状态的灯的编号。 答案:最后为关灯状态的有1、4、9、16、25、36、49、64、81、100共10个数,就是1~10的平方数。只有这些数有奇数个约数。
-
假设一张圆盘像唱机上的唱盘那样转动。这张盘一半是黑色,一半是白色。假设你有数量不限的一些颜色传感器。要想确定圆盘转动的方向,你需要在它周围摆多少个颜色传感器?它们应该被摆放在什么位置? 答案:2个为a,b,均放在左侧a在左上,b在左下,若a先于b变化,则顺时针,b先于a变化,则逆时针。
-
假设时钟到了12点。注意时针和分针重叠在一起。在一天之中,时针和分针共重叠多少次?你知道它们重叠时的具体时间吗? 答案:24小时,时针走2圈,分针走24圈,分针超时针22圈,重合22次. (1) 00:00:00, (2) 01:05:27, (3) 02:10:54, (4) 03:16:21, (5) 04:21:49, (6) 05:27:16, (7) 06:32:43, (8) 07:38:10, (9) 08:43:38, (10) 09:49:05, (11) 10:54:32, (12) 12:00:00, (13) 13:05:27, (14) 14:10:54, (15) 15:16:21, (16) 16:21:49, (17) 17:27:16, (18) 18:32:43, (19) 19:38:10, (20) 20:43:38, (21) 21:49:05, (22) 22:54:32。
-
一个屋子有一个门(门是关闭的)和3盏电灯。屋外有3个开关,分别与这3盏灯相连。你可以随意操纵这些开关,可一旦你将门打开,就不能变换开关了。确定每个开关具体管哪盏灯。 答案:先打开一盏灯,等它亮几分钟,关上这盏再开另外一盏,然后开门进去摸一摸灯泡,发热的那个就是之前的那盏灯,亮着的就是第二盏,一直没打开过的那盏灯也就出来了,
-
假设你有8个球,其中一个略微重一些,但是找出这个球的惟一方法是将两个球放在天平上对比。最少要称多少次才能找出这个较重的球? (7个球找1个也是2次,分为3,3,1) 答案:两次。将8个球分成3组,分别有3.3.2个。将两组3个球的作为一个整体分别放到天平两端,如不平衡,将轻的一侧再分3组重复上述步骤。如平衡,将剩下的两个球分别放在天平两端。
-
如果你有两个桶,一个装的是红色的颜料,另一个装的是蓝色的颜料。你从蓝色颜料桶里舀一杯,倒入红色颜料桶,再从红色颜料桶里舀一杯倒入蓝颜料桶。两个桶中红蓝颜料的比例哪个更高?通过算术的方式来证明这一点。 答案:红桶的高,设红桶中有颜料a升,蓝桶有a升,每杯有n升,题目要求a大于n,那么:红桶中,红:蓝=a:n,蓝桶中,红:蓝=(a*n/(a+n)):(a-n+n^2/(a+n))=a*n:a^2=n:a。因为a大于n,所以,红桶中比例大于1,蓝桶中比例小于1。
sql server 查询某个表被哪些存储过程调用
select distinct object_name(id) from syscomments where id in
(select id from sysobjects where type =’P’) and text like’%TableName%’
DataTable根据字段去重
最近需要对datatable根据字段去重,在网上搜了很多,找到了一个方法,代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public static DataTable DistinctSomeColumn(DataTable sourceTable, params string [] fieldName)
{
DataTable dt2 = sourceTable.Clone();
DataView v1 = dt2.DefaultView;
StringBuilder filter = new StringBuilder();
foreach (DataRow row in sourceTable.Rows)
{
for ( int i = 0; i < fieldName.Length; i++)
{
filter.AppendFormat( "{0}='{1}'" , fieldName[i], row[fieldName[i]].ToString().TrimEnd());
if (i < fieldName.Length - 1)
{
filter.Append( " and " );
}
}
v1.RowFilter = filter.ToString();
if (v1.Count > 0)
{
filter = new StringBuilder();
continue ;
}
dt2.Rows.Add(row.ItemArray);
filter = new StringBuilder();
}
return dt2;
}
|
经过测试,代码可以实现功能,但是其中有一点弄不明白,DataView v1 = dt2.DefaultView;这里对dt2做加入行操作,同时也能影响v1,但是经过我测试如果直接把新的一个datatable赋给dt2,则不能影响v1,还有dataview里的table属性又是什么,找了好多资料都没弄清楚,有大神解释一下吗。
同源策略和资源跨域共享
1、同源策略
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。
1.1、目的
主要是为了保证用户信息的安全,防止网站窃取用户数据。假如没有同源策略,可能就会有下面这种情况的发生。用户访问两个网站A/B,并登录了A网站,A网站会在计算机本地存储Cookie或者Token等等,在访问B网站的时候,B网站就可以访问这些本地的存储信息,B网站可以使用用户的Cookie去登录A网站,那这样用户信息就被泄露了。
1.2、限制范围
- Cookie、LocalStorage和indexDB无法访问(只有同源的网页才能共享Cookie)
- DOM无法获得(父窗口和子窗口的地址是同源的才能获取子窗口的信息)
- AJAX请求不能被发送(AJAX请求只能发送给同源的网址)
要知道一点,这些限制其实都是浏览器做的限制。
2、跨域资源共享
跨域资源共享跟同源策略相反。在整个跨域通信过程中,浏览器会自动识别此次请求是否跨域,一旦发现跨域,就自动添加请求头信息(如Origin)或者自动发送一次请求方式为option的预请求。浏览器将CORS请求分为两类:简单请求和非简单请求。
2.1、简单请求
当浏览器的请求方式是Head、Get或者Post,并且HTTP的头信息中不会超出以下字段:
-
Accept
-
Accept-Language
-
Content-Language
-
Origin
时,浏览器会将该请求定义为简单请求,否则就是非简单请求。当浏览器判断为简单请求后,浏览器会自动再请求报文头中加上Origin字段,表明此次请求来自的地址(协议+域名+端口)。然后服务器需要去判断是否接受这个来源的请求。如果允许服务器端返回的头部中需要有Access-Control-Allow-Origin,其值为请求时Origin字段的值或*(表示接受任意源的请求)。请求头中还会有Access-Control-Allow-Methods表示服务器允许的跨域请求的方式。Access-Control-Allow-Headers表示请求头中允许出现的字段。
2.2、 非简单请求
当浏览器判断为非简单请求后,会发送两次请求,首先浏览器会自动发送一个请求方式为options的请求,并在请求头中
- 加上Access-Control-Request-Method表示下次请求的方法,
- 加上Origin表明来源,
- 加上Access-Control-Request-Headers表示下次请求的请求头中额外的字段。
服务器收到请求后,需要获取这三个请求头中的值,并进行判断,确认是否允许进行跨域。如果服务器返回的请求头中没有任何CORS相关的请求头信息,浏览器会认为不通过预检,也不会进行第二次请求。
服务器如果接受跨域并验证通过了options的请求,会返回Access-Control-Allow-Origin(表明允许跨域请求的源)、Access-Control-Allow-Methods(允许跨域请求的请求方式)、Access-Control-Allow-Headers(允许请求头中包含的额外字段)。然后浏览器才会发送真正的请求。
(第一次options请求)
(第二次请求)
二、服务端实现CORS
在.Net Core Web Api中使用很简单,首先安装包Microsoft.AspNet.WebApi.Cors,在StartUp中添加下面两句
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
//添加Cors,并配置CorsPolicy
services.AddCors(options => options.AddPolicy("CorsTest", p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
} //注意UseCors()要在UseMvc()之前
app.UseCors("CorsTest");
app.UseMvc();
}
在使用的时候只需要在Controller或者Action中加上特性[EnableCors("CorsTest")]
[EnableCors("CorsTest")]
public class ValuesController : Controller
{
private ILogger<ValuesController> _logger;
public ValuesController(ILogger<ValuesController> logger)
{
_logger = logger;
}
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
现在服务端已经配置好了,现在需要通过前端跨域请求
<html>
<head>
测试
</head>
<body>
测试
</body>
</html>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
$(function () {
$.ajax({
type: "get",
url: "http://localhost:7000/api/values",
beforeSend: function (request) {//在请求报文头中加入Authorization 目的是让请求为非简单请求
request.setRequestHeader("Authorization", "Bearer 071899A00D4D4C5B1C41A6B0211B9399");
},
success: function (result) {
alert(result);
}
}, "json");
});
</script>
测试结果如下图:
(options请求)
(第二次请求)
上面配置允许所有的地址请求这个接口,也可以单独配置某个地址。
services.AddCors(options => options.AddPolicy("CorsTest", p => p.WithOrigins("http://localhost:8089")
.AllowAnyHeader()
.AllowAnyMethod()));
三、解析Cors源码
打开CORS源码,主要的是CorsMiddleware、CorsOptions、CorsPolicy、CorsPolicyBuilder、CorsResult、CorsService这几个类。
- CorsPolicy:就是我们在Startup中的配置,如允许哪些域名可以跨域请求,允许哪些跨域请求方式,允许哪些额外的请求头,每个配置对应一个名称。
services.AddCors(options => options.AddPolicy("CorsTest", p => p.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()));
- CorsOptions:中包含一个字典IDictionary<string, CorsPolicy> PolicyMap,一个项目可能有过个Cors配置,所以这个CorsOptions就是通过配置名称管理这些配置的。
- CorsPolicyBuilder:通过它来构造CorsPolicy。
- CorsResult:是验证跨域过程得到的结果。如在第一次Options请求时,客户端发送了Origi:http://localhost:8089,服务器会返回Access-Control-Allow-Origin:http://localhost:8089,服务器验证http://localhost:8089这个域名是否允许跨域,如果允许就将“http://localhost:8089”这个值存储到CorsResult的AllowedHeaders中,在请求(第一次请求)返回的时候将这些加到HTTP请求头中。
- CorsMiddleware:Cors中间件类,主要方法就是Invoke,每次HTTP请求都会调用这个方法。
public async Task Invoke(HttpContext context)
{//判断HTTP请求头是否有Origin,由此判断是不是跨域请求
if (context.Request.Headers.ContainsKey(CorsConstants.Origin))
{
var corsPolicy = _policy ?? await _corsPolicyProvider?.GetPolicyAsync(context, _corsPolicyName);
if (corsPolicy != null)
{
var accessControlRequestMethod = context.Request.Headers[CorsConstants.AccessControlRequestMethod]; //如果是跨域请求 判断是不是第一次Options请求
if (string.Equals(context.Request.Method,CorsConstants.PreflightHttpMethod,StringComparison.OrdinalIgnoreCase)
&&!StringValues.IsNullOrEmpty(accessControlRequestMethod))
{ //判断是否允许当前请求跨域,根据HttpContext的内容和Cors配置 得到CorsResult,然后将CorsResult的内容添加到请求头中(看下面详细解释)
ApplyCorsHeaders(context, corsPolicy);
context.Response.StatusCode = StatusCodes.Status204NoContent;
return;
}
else
{// 执行第二次非Options请求
context.Response.OnStarting(state =>
{
var (httpContext, policy) = (Tuple<HttpContext, CorsPolicy>)state;
try
{
ApplyCorsHeaders(httpContext, policy);
}
catch (Exception exception)
{
_logger.FailedToSetCorsHeaders(exception);
}
return Task.CompletedTask;
}, Tuple.Create(context, corsPolicy));
}
}
}
await _next(context);
}
private void ApplyCorsHeaders(HttpContext context, CorsPolicy corsPolicy)
{ //通过HTTP上下文请求的数据和Cors配置 得到CorsResult 如在第一次Options请求时,客户端发送了Origi:http://localhost:8089,Access-Control-Resquest-Methods:GET 服务器会返回Access-Control-Allow-Origin:http://localhost:8089,Access-Control-Allow-Methods:GET 服务器验证http://localhost:8089这个域名以GET请求方式是否允许跨域, 如果允许就将“http://localhost:8089”这个值存储到CorsResult的AllowedHeaders中 将"GET"存储到CorsResult的AllowedMethods中
var corsResult = _corsService.EvaluatePolicy(context, corsPolicy); //将CorsResult中的值添加到相应头中的,返回到客户端
_corsService.ApplyResult(corsResult, context.Response);
}
相对来说Cors源码还是比较简单的,很容易看懂。可以自己写一个项目,然后挂上源码单步调试。
要想分析MySQL查询语句中的相关信息,如是全表查询还是部分查询,就要用到explain.
一、explain
用法:explain +查询语句。
id:查询语句的序列号,上面图片中只有一个select 语句,所以只会显示一个序列号。如果有嵌套查询,如下
select_type:表示查询类型,有以下几种
simple: 简单的 select (没有使用 union或子查询)
primary: 最外层的 select。
union: 第二层,在select 之后使用了 union。
dependent union: union 语句中的第二个select,依赖于外部子查询
subquery: 子查询中的第一个 select
dependent subquery: 子查询中的第一个 subquery依赖于外部的子查询
derived: 派生表 select(from子句中的子查询)
table:查询的表、结果集
type:全称为"join type",意为连接类型。通俗的讲就是mysql查找引擎找到满足SQL条件的数据的方式。其值为:
- system:系统表,表中只有一行数据
- const:读常量,最多只会有一条记录匹配,由于是常量,实际上只须要读一次。
- eq_ref:最多只会有一条匹配结果,一般是通过主键或唯一键索引来访问。
- ref:对于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取
- fulltext:进行全文索引检索。
- ref_or_null:与ref的唯一区别就是在使用索引引用的查询之外再增加一个空值的查询。
- index_merge:查询中同时使用两个(或更多)索引,然后对索引结果进行合并,再读取表数据。
- unique_subquery:子查询中的返回结果字段组合是主键或者唯一约束。
- index_subquery:子查询中的返回结果字段组合是一个索引(或索引组合),但不是一个主键或唯一索引。
- rang:索引范围扫描。
- index:全索引扫描。
- all:全表扫描。
性能从上到下依次降低。
possible_keys:可能用到的索引
key:使用的索引
ref: ref列显示使用哪个列或常数与key一起从表中选择行。
rows:显示MySQL认为它执行查询时必须检查的行数。多行之间的数据相乘可以估算要处理的行数。
Extra:额外的信息
-
Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
-
Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
-
range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
-
Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。
-
Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。
-
Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。
-
Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。
-
Using sort_union(...), Using union(...), Using intersect(...):这些函数说明如何为index_merge联接类型合并索引扫描。
-
Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。
二、数据库不使用索引的情况
下面举的例子中,GudiNo、StoreId列都有单独的索引。
2.1、like查询已 '%...'开头,以'xxx%'结尾会继续使用索引。
下图中第一句使用的%,没有使用索引,从rows为224147,使用索引rows为1。
2.2 where语句中使用 <>和 !=
2.3 where语句中使用 or,但是没有把or中所有字段加上索引。
这种情况,如果需要使用索引需要将or中所有的字段都加上索引。
2.4 where语句中对字段表达式操作
2.5 where语句中使用Not In
看了别人写的文章,有说“应尽量避免在where 子句中对字段进行null 值判断,否则将导致引擎放弃使用索引而进行全表扫描”,实测没有全表扫描。
"对于多列索引,不是使用的第一部分,则不会使用索引",实测即使多索引,没有使用第一部分,也会命中索引,没有全表扫描。
记录最近一次的项目开发中遇到的问题和解决方式。在给移动端开放数据接口的时候,移动端开放人员反映部署到测试环境的接口调用访问出现了问题,但是在单独进行访问是可以正常的。那么,问题就来了。
根据查询园子里大佬们的文章,了解到问题的根源。
问题的由来:该问题的出现是因为浏览器出于安全考虑,浏览器会限制脚本中发起跨域请求(有一个项目是使用的后台做的请求,类似微信接口调用的方式,未出现改问题),JavaScript或者Cookie只能访问同域下的资源-----所谓的“同源策略”,正是这个原因导致了移动端开发人员在H5页面上使用脚本异步访问接口被浏览器阻止了。
问题的解决方案:针对ASP.NET Web API 只需在web.config文件下添加相关的配置内容就可以解决了
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /> </customHeaders> </httpProtocol>
<handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer>
添加完配置后,基本上是可以解决跨域的问题了,当然还有CORS的跨域解决方案,只是还没有去了解和使用过,这里就不进行记录了。
-
你让工人为你工作7天,给工人的回报是一根金条。金条平分成相连的7段,你必须在每天结束时给他们一段金条,如果只许你两次把金条弄断,你如何给你的工人付费? 答案:第一天给1段,第二天让工人把1段归还后再给他给2段,第三天给1段,第四天让工人归还1、2段,给4段。第五天依次类推……
-
请把一盒蛋糕切成8份,分给8个人,但蛋糕盒里还必须留有一份。 答案:面对这样的怪题,有些应聘者绞尽脑汁也无法分成;而有些应聘者却感到此题实际很简单,把切成的8份蛋糕先拿出7份分给7人,剩下的1份连蛋糕盒一起分给第8个人。
-
小明一家过一座桥,过桥时是黑夜,所以必须有灯。现在小明过桥要1秒,小明的弟弟要3秒,小明的爸爸要6秒,小明的妈妈要8秒,小明的爷爷要12秒。每次此桥最多可过两人,而过桥的速度依过桥最慢者而定,而且灯在点燃后30秒就会熄灭。问:小明一家如何过桥? 答案:这类智力题目,其实是考察应聘者在限制条件下解决问题的能力。具体到这道题目来说,很多人往往认为应该由小明持灯来来去去,这样最节省时间,但最后却怎么也凑不出解决方案。但是换个思路,我们根据具体情况来决定谁持灯来去,只要稍稍做些变动即可:第一步,小明与弟弟过桥,小明回来,耗时4秒;第二步,小明与爸爸过河,弟弟回来,耗时9秒;第三步,妈妈与爷爷过河,小明回来,耗时13秒;最后,小明与弟弟过河(不用回来了),耗时3秒,总共耗时29秒。
-
一群人开舞会,每人头上都戴着一顶帽子。帽子只有黑白两种,黑的至少有一顶。每个人都能看到其他人帽子的颜色,却看不到自己的。主持人先让大家看看别人头上戴的是什么帽子,然后关灯,如果有人认为自己戴的是黑帽子,就打自己一个耳光。第一次关灯,没有声音。于是再开灯,大家再看一遍,关灯时仍然鸦雀无声。一直到第三次关灯,才有劈劈啪啪打耳光的声音响起。问有多少人戴着黑帽子? 答案:假如只有一个人戴黑帽子,那他看到所有人都戴白帽,在第一次关灯时就应自打耳光,所以应该不止一个人戴黑帽子;如果有两顶黑帽子,第一次两人都只看到对方头上的黑帽子,不敢确定自己的颜色,但到第二次关灯,这两人应该明白,如果自己戴着白帽,那对方早在上一次就应打耳光了,因此自己戴的也是黑帽子,于是也会有耳光声响起;可事实是第三次才响起了耳光声,说明全场不止两顶黑帽,依此类推,应该是关了几次灯,有几顶黑帽。
-
一楼到十楼的每层电梯门口都放着一颗钻石,钻石大小不一。你乘坐电梯从一楼到十楼,每层楼电梯门都会打开一次,只能拿一次钻石,问怎样才能拿到最大的一颗? 答案:这是一道没有标准答案的试题,实际上它考的是你的开放性思维和逻辑推理能力. 第一步:对1到3层的大小进行比较,记住最大的一颗。 第二步:4到6层作为参考,将4-6层的最大的跟1-3层的最大的作比较,确认最大的一个的平均水平。 第三步:在最后4层中选择一个属于最大一批的,如果第7层的就是最大的平均水平的,那就闭上眼睛不再观察之后的。这就是最大的一颗。
-
烧一根不均匀的绳要用一个小时,如何用它来判断半个小时? 答案:两边一起烧。
-
为什么下水道的盖子是圆的? 答案之一:从麻省理工大学一位计算机系教授那里听来的答案,首先在同等用材的情况下他的面积最大。第二因为如果是方的、长方的或椭圆的,那无聊之徒拎起来它就可以直接扔进地下道啦!但圆形的盖子嘛,就可以避免这种情况了
-
有7克、2克砝码各一个,天平一只,如何只用这些物品三次将140克的盐分成50、90克各一份? 答案:(1)用天平把140g分成两等份,每份70g; (2)用天平把其中一份70g分成两等份,每份35g; (3)取其中一份35g放到天平的一端,把7g的砝码也放到这一端,再把2g的砝码放到天平的另一端.从7g砝码一端移取盐到2g砝码的一端,直到天平平衡.这时,2g砝码一端盐的量为20g.把这20g和已开始分出的未动一份70g盐放在一起,就是90g,其他的盐放在一起,就是50g.
-
想象你在镜子前,请问,为什么镜子中的影像可以颠倒左右,却不能颠倒上下? 答案:因为人的两眼在水平方向上对称。
-
你有两个罐子,50个红色弹球,50个蓝色弹球,随机选出一个罐子,随机选取出一个弹球放入罐子,怎么给红色弹球最大的选中机会?在你的计划中,得到红球的准确几率是多少? 答案:一个罐子放一个红球,另一个罐子放49个红球和50个蓝球,概率接近75%. 这是所能达到的最大概率了。 实际上,只要一个罐子放<50个红球,不放篮球,另一个罐子放剩下的球,拿出红球的概率就大于50%。
-
你有四人装药丸的罐子,每个药丸都有一定的重量,被污染的药丸是没被污染的重量+1.只称量一次,如何判断哪个罐子的药被污染了? 答案:先假设每颗药丸重x克,然后每个罐取分别标上1,2,3,4号.一号取一颗药丸,二号取两颗药丸,是几号就取几颗,一起称,如果是一号被污染质量为(10x+1),二号被污染质量为(10x+2),依此类推.
-
对一批编号为1~100 全部开关朝上开的灯进行以下操作凡是1 的倍数反方向拨一次开关2 的倍数反方向又拨一次开关3 的倍数反方向又拨一次开关。问最后为关熄状态的灯的编号。 答案:最后为关灯状态的有1、4、9、16、25、36、49、64、81、100共10个数,就是1~10的平方数。只有这些数有奇数个约数。
-
假设一张圆盘像唱机上的唱盘那样转动。这张盘一半是黑色,一半是白色。假设你有数量不限的一些颜色传感器。要想确定圆盘转动的方向,你需要在它周围摆多少个颜色传感器?它们应该被摆放在什么位置? 答案:2个为a,b,均放在左侧a在左上,b在左下,若a先于b变化,则顺时针,b先于a变化,则逆时针。
-
假设时钟到了12点。注意时针和分针重叠在一起。在一天之中,时针和分针共重叠多少次?你知道它们重叠时的具体时间吗? 答案:24小时,时针走2圈,分针走24圈,分针超时针22圈,重合22次. (1) 00:00:00, (2) 01:05:27, (3) 02:10:54, (4) 03:16:21, (5) 04:21:49, (6) 05:27:16, (7) 06:32:43, (8) 07:38:10, (9) 08:43:38, (10) 09:49:05, (11) 10:54:32, (12) 12:00:00, (13) 13:05:27, (14) 14:10:54, (15) 15:16:21, (16) 16:21:49, (17) 17:27:16, (18) 18:32:43, (19) 19:38:10, (20) 20:43:38, (21) 21:49:05, (22) 22:54:32。
-
一个屋子有一个门(门是关闭的)和3盏电灯。屋外有3个开关,分别与这3盏灯相连。你可以随意操纵这些开关,可一旦你将门打开,就不能变换开关了。确定每个开关具体管哪盏灯。 答案:先打开一盏灯,等它亮几分钟,关上这盏再开另外一盏,然后开门进去摸一摸灯泡,发热的那个就是之前的那盏灯,亮着的就是第二盏,一直没打开过的那盏灯也就出来了,
-
假设你有8个球,其中一个略微重一些,但是找出这个球的惟一方法是将两个球放在天平上对比。最少要称多少次才能找出这个较重的球? (7个球找1个也是2次,分为3,3,1) 答案:两次。将8个球分成3组,分别有3.3.2个。将两组3个球的作为一个整体分别放到天平两端,如不平衡,将轻的一侧再分3组重复上述步骤。如平衡,将剩下的两个球分别放在天平两端。
-
如果你有两个桶,一个装的是红色的颜料,另一个装的是蓝色的颜料。你从蓝色颜料桶里舀一杯,倒入红色颜料桶,再从红色颜料桶里舀一杯倒入蓝颜料桶。两个桶中红蓝颜料的比例哪个更高?通过算术的方式来证明这一点。 答案:红桶的高,设红桶中有颜料a升,蓝桶有a升,每杯有n升,题目要求a大于n,那么:红桶中,红:蓝=a:n,蓝桶中,红:蓝=(a*n/(a+n)):(a-n+n^2/(a+n))=a*n:a^2=n:a。因为a大于n,所以,红桶中比例大于1,蓝桶中比例小于1。
sql server 查询某个表被哪些存储过程调用
select distinct object_name(id) from syscomments where id in
(select id from sysobjects where type =’P’) and text like’%TableName%’
DataTable根据字段去重
最近需要对datatable根据字段去重,在网上搜了很多,找到了一个方法,代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public static DataTable DistinctSomeColumn(DataTable sourceTable, params string [] fieldName)
{
DataTable dt2 = sourceTable.Clone();
DataView v1 = dt2.DefaultView;
StringBuilder filter = new StringBuilder();
foreach (DataRow row in sourceTable.Rows)
{
for ( int i = 0; i < fieldName.Length; i++)
{
filter.AppendFormat( "{0}='{1}'" , fieldName[i], row[fieldName[i]].ToString().TrimEnd());
if (i < fieldName.Length - 1)
{
filter.Append( " and " );
}
}
v1.RowFilter = filter.ToString();
if (v1.Count > 0)
{
filter = new StringBuilder();
continue ;
}
dt2.Rows.Add(row.ItemArray);
filter = new StringBuilder();
}
return dt2;
}
|
经过测试,代码可以实现功能,但是其中有一点弄不明白,DataView v1 = dt2.DefaultView;这里对dt2做加入行操作,同时也能影响v1,但是经过我测试如果直接把新的一个datatable赋给dt2,则不能影响v1,还有dataview里的table属性又是什么,找了好多资料都没弄清楚,有大神解释一下吗。
同源策略和资源跨域共享
1、同源策略
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。
1.1、目的
主要是为了保证用户信息的安全,防止网站窃取用户数据。假如没有同源策略,可能就会有下面这种情况的发生。用户访问两个网站A/B,并登录了A网站,A网站会在计算机本地存储Cookie或者Token等等,在访问B网站的时候,B网站就可以访问这些本地的存储信息,B网站可以使用用户的Cookie去登录A网站,那这样用户信息就被泄露了。
1.2、限制范围
- Cookie、LocalStorage和indexDB无法访问(只有同源的网页才能共享Cookie)
- DOM无法获得(父窗口和子窗口的地址是同源的才能获取子窗口的信息)
- AJAX请求不能被发送(AJAX请求只能发送给同源的网址)
要知道一点,这些限制其实都是浏览器做的限制。
2、跨域资源共享
跨域资源共享跟同源策略相反。在整个跨域通信过程中,浏览器会自动识别此次请求是否跨域,一旦发现跨域,就自动添加请求头信息(如Origin)或者自动发送一次请求方式为option的预请求。浏览器将CORS请求分为两类:简单请求和非简单请求。
2.1、简单请求
当浏览器的请求方式是Head、Get或者Post,并且HTTP的头信息中不会超出以下字段:
-
Accept
-
Accept-Language
-
Content-Language
-
Origin
时,浏览器会将该请求定义为简单请求,否则就是非简单请求。当浏览器判断为简单请求后,浏览器会自动再请求报文头中加上Origin字段,表明此次请求来自的地址(协议+域名+端口)。然后服务器需要去判断是否接受这个来源的请求。如果允许服务器端返回的头部中需要有Access-Control-Allow-Origin,其值为请求时Origin字段的值或*(表示接受任意源的请求)。请求头中还会有Access-Control-Allow-Methods表示服务器允许的跨域请求的方式。Access-Control-Allow-Headers表示请求头中允许出现的字段。
2.2、 非简单请求
当浏览器判断为非简单请求后,会发送两次请求,首先浏览器会自动发送一个请求方式为options的请求,并在请求头中
- 加上Access-Control-Request-Method表示下次请求的方法,
- 加上Origin表明来源,
- 加上Access-Control-Request-Headers表示下次请求的请求头中额外的字段。
服务器收到请求后,需要获取这三个请求头中的值,并进行判断,确认是否允许进行跨域。如果服务器返回的请求头中没有任何CORS相关的请求头信息,浏览器会认为不通过预检,也不会进行第二次请求。
服务器如果接受跨域并验证通过了options的请求,会返回Access-Control-Allow-Origin(表明允许跨域请求的源)、Access-Control-Allow-Methods(允许跨域请求的请求方式)、Access-Control-Allow-Headers(允许请求头中包含的额外字段)。然后浏览器才会发送真正的请求。
|
请发表评论