|
1 2 |
//通知一个或多个正在等待的线程已发生事件。 ManualResetEvent manager = new ManualResetEvent(false); |
|
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 29 30 31 32 33 34 35 36 |
//负责监听的套接字 private Socket socketServer; /// <summary> /// 启动服务 /// </summary> private void CreateSocketService() { try { //获取IP var address = IPAddress.Parse(txtIP.Text.Trim()); //创建一个包含ip port 的网络节点对象 var ipPoint = new IPEndPoint(address, Convert.ToInt32(txtPort.Text.Trim())); //创建一个套接字socket,参数(IP4寻址协议,流式连接,使用TCP协议传输数据) socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //将负责监听的套接字绑定到唯一的IP和端口上 socketServer.Bind(ipPoint); //设置监听队列的长度,同时100个队列 socketServer.Listen(100); //线程开始监听客户端的请求 threadService = new Thread(StartSocketService); //设置线程为后台线程 threadService.IsBackground = true; //启动线程 threadService.Start(); //显示消息 ShowMsg("服务器监听开启成功!"); } catch (Exception e) { ShowMsg(e.Message); } } |
|
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 |
/// <summary> /// 启动服务监听 /// </summary> private void StartSocketService() { while (true) { try { //将事件状态设置为非终止状态,导致线程阻止 manager.Reset(); //开始监听客户端的连接请求 var args = new SocketAsyncEventArgs(); args.Completed += args_Completed; socketServer.AcceptAsync(args); //WaitHandle receives a signal." data-guid="dd8c3ab0d5ce03487bc8a650ef1c15c8">阻止当前线程,直到当前 WaitHandle 收到信号。 manager.WaitOne(); } catch (Exception ex) { ShowMsg(ex.Message); break; } } } |
|
1 2 3 4 5 6 7 8 9 |
void args_Completed(object sender, SocketAsyncEventArgs e) { //监听完成客户端的请求,一但监听到返回新的套接字 var clientSocket = e.AcceptSocket; //启动线程获取客户端发来的消息 if (clientSocket == null) return; //开始接受消息....... //该函数未写完,第二篇补全 } |
|
1 2 3 4 5 |
void ShowMsg(string message) { //显示消息 txtConneMsg.AppendText("\r\n" + DateTime.Now + "\r\n\r\n" + message + "\r\n"); } |
ok 服务监听就启动成功了,正等待客户端连接。
|
1 |
ManualResetEvent reviceManager = new ManualResetEvent(false); |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public void args_Completed(object sender, SocketAsyncEventArgs e) { //监听完成客户端的请求,一但监听到返回新的套接字 var clientSocket = e.AcceptSocket; if (clientSocket == null) return; //启动线程获取客户端发来的消息 //这部分为接收消息 var t = new Thread(GetClientMsg); //设置线程为后台线程 t.IsBackground = true; //启动线程 t.Start(clientSocket); //显示信息 ShowMsg(clientSocket.RemoteEndPoint + "上线了"); //将事件状态设置为终止状态,允许一个或多个等待线程继续 manager.Set(); } |
建议对照 C# Socket基础(一)之启动异步服务侦听 来看。
|
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 |
private void GetClientMsg(object socket) { var socketClient = socket as Socket; if (socketClient == null) return; while (true) { try { reviceManager.Reset(); var bytes = new byte[1024 * 1024 * 4]; var receiveArgs = new SocketAsyncEventArgs(); //设置缓冲区 receiveArgs.SetBuffer(bytes, 0, bytes.Length); receiveArgs.Completed += receiveArgs_Completed; //开始异步接收 socketClient.ReceiveAsync(receiveArgs); reviceManager.WaitOne(); } catch (Exception ex) { //显示异常消息 ShowMsg(ex.Message); } } } |
接收消息完成回调事件
|
1 2 3 4 5 6 7 |
void receiveArgs_Completed(object sender, SocketAsyncEventArgs e) { var socketClient = sender as Socket; var bytes = e.Buffer; ShowMsg(socketClient.RemoteEndPoint + "说:" + System.Text.Encoding.UTF8.GetString(bytes)); reviceManager.Set(); } |
又与大家见面,看不懂的随时问。
|
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 29 30 31 32 33 34 35 |
private Thread threadClient;//客户端线程 private Socket socketClient;//客户端套接字 /// <summary> /// 创建套接字连接到服务端 /// </summary> private void CreateSocketConnection() { try { //创建一个客户端的套接字 参数(IP4寻址协议,流连接方式,TCP数据传输协议) socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //获取IP IPAddress address = IPAddress.Parse(txtIP.Text.Trim()); //创建一个包含IP和端口号的网络节点对象 IPEndPoint ipPoint = new IPEndPoint(address, Convert.ToInt32(txtPort.Text.Trim())); // 连接服务端 socketClient.Connect(ipPoint); //创建一个线程,接受服务端发来的数据 threadClient = new Thread(ReceiveService); //设置线程为后台线程 threadClient.IsBackground = true; //启动线程连接服务端 threadClient.Start(); //显示消息 ShowMsg("与服务器" + txtIP.Text.Trim() + ":" + txtPort.Text + "成功建立连接!"); } catch (Exception) { ShowMsg(txtIP.Text.Trim() + ":" + txtPort.Text + "服务器未启动!"); } } |
客户端接收消息
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
private void ReceiveService() { while (true) { try { int num = -1; var b = new byte[1024 * 1024 * 4]; int length = socketClient.Receive(b); var msg = System.Text.Encoding.UTF8.GetString(b,0,length); ShowMsg(socketClient.RemoteEndPoint.ToString() + "对您: " + msg); } catch (Exception ex) { ShowMsg(ex.Message); break; } } } |
|
1 2 3 4 |
private void ShowMsg(string msg) { txtConneMsg.AppendText("\r\n" + DateTime.Now + "\r\n\r\n" + msg + "\r\n"); } |
客户端: 服务器: 客户端接收到消息: private Socket socketClient;//客户端套接字,关于实例化请参考C# Socket基础(三)之客户端连接服务器和接收消息 客户端发送消息
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
/// <summary> /// 发送数据到服务端 /// </summary> private void Send() { if (socketClient == null) { ShowMsg("服务器未启动!"); return; } byte[] b = System.Text.Encoding.UTF8.GetBytes(txtSend.Text.Trim()); //客户端向服务器发送消息 socketClient.Send(b); //清空文本 ShowMsg("您对" + socketClient.RemoteEndPoint.ToString() + "说:" + txtSend.Text.Trim()); txtSend.Text = ""; } |
关于 ShowMsg(string message);是自定义的函数,在C# Socket基础(一)之启动异步服务侦听 好了,到这里就要告一段落了,实现了基本的客户端和服务器采用TCP协议通信。 看看效果吧: 客户端: 服务器: from:https://www.cnblogs.com/aaa6818162/p/3862159.html
View Details安装适用于 Linux 的 Windows 子系统 在安装适用于 WSL 的任何 Linux 分发版之前,必须确保已启用“适用于 Linux 的 Windows 子系统”可选功能: 以管理员身份打开 PowerShell 并运行: PowerShell复制
|
1 2 |
<span class="hljs-pscommand">Enable-WindowsOptionalFeature</span><span class="hljs-parameter"> -Online</span><span class="hljs-parameter"> -FeatureName</span> <span class="hljs-pscommand">Microsoft-Windows</span>-<span class="hljs-pscommand">Subsystem-Linux</span> |
出现提示时,重启计算机。 安装所选的 Linux 分发版 若要下载并安装首选的分发版,可以选择三种做法: 从 Microsoft Store 下载并安装(参阅下文) 从命令行/脚本下载并安装(阅读手动安装说明) 下载并手动解压缩和安装(适用于 Windows Server – 参阅此处的说明) Windows 10 Fall Creators Update 和更高版本:从 Microsoft Store 安装 本部分适用于 Windows 内部版本 16215 或更高版本。 遵循以下步骤检查内部版本。 打开 Microsoft Store,并选择你偏好的 Linux 分发版。 单击以下链接会打开每个分发版的 Microsoft Store 页面: Ubuntu 16.04 LTS Ubuntu 18.04 LTS OpenSUSE Leap 15 OpenSUSE Leap 42 SUSE Linux Enterprise Server 12 SUSE Linux Enterprise Server 15 Kali Linux Debian GNU/Linux Fedora Remix for WSL Pengwin Pengwin […]
View DetailsWSL 的运行方式 可通过多种方式配合适用于 Linux 的 Windows 子系统运行 Linux。 [distro],例如 ubuntu wsl.exe 或 bash.exe wsl [command] 或 bash -c [command] 要使用的方法取决于执行的操作。 按分发版启动 WSL 使用特定于分发版的应用程序运行某个分发版会在其自身的控制台窗口中将它启动。 这相当于在 Microsoft Store 中单击“启动”。 还可以在命令行中运行 [distribution].exe 来运行分发版。 以这种方式从命令行运行分发版的缺点是,会自动将工作目录从当前目录更改为分发版的主目录。 示例: console复制
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
PS C:\Users\sarah> pwd Path ---- C:\Users\sarah PS C:\Users\sarah> ubuntu scooley@scooley-elmer:~$ pwd /home/scooley scooley@scooley-elmer:~$ exit logout PS C:\Users\sarah> |
wsl 和 wsl [命令] 从命令行运行 WSL 的最佳方式是使用 wsl.exe。 示例: console复制
|
1 2 3 4 5 6 7 8 9 10 11 |
PS C:\Users\sarah> pwd Path ---- C:\Users\sarah PS C:\Users\sarah> wsl scooley@scooley-elmer:/mnt/c/Users/sarah$ pwd /mnt/c/Users/sarah |
这样,wsl 不仅可以保留当前工作目录,而且还允许结合 Windows 命令运行单个命令。 示例: console复制
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
PS C:\Users\sarah> Get-Date Sunday, March 11, 2018 7:54:05 PM PS C:\Users\sarah> wsl scooley@scooley-elmer:/mnt/c/Users/sarah$ date Sun Mar 11 19:56:57 DST 2018 scooley@scooley-elmer:/mnt/c/Users/sarah$ exit logout PS C:\Users\sarah> wsl date Sun Mar 11 19:55:47 DST 2018 |
示例: console复制
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
PS C:\Users\sarah> Get-VM Name State CPUUsage(%) MemoryAssigned(M) Uptime Status ---- ----- ----------- ----------------- ------ ------ Server17093 Off 0 0 00:00:00 Opera... Ubuntu Off 0 0 00:00:00 Opera... Ubuntu (bionic) Off 0 0 00:00:00 Opera... Windows Off 0 0 00:00:00 Opera... PS C:\Users\sarah> Get-VM | wsl grep "Ubuntu" Ubuntu Off 0 0 00:00:00 Opera... Ubuntu (bionic) Off 0 0 00:00:00 Opera... PS C:\Users\sarah> |
管理多个 Linux 分发版 Windows 10 版本 1903 和更高版本 可以使用 wsl.exe 管理适用于 Linux 的 Windows 子系统 (WSL) 中的分发版,包括列出可用分发版、设置默认分发版,以及卸载分发版。 每个 Linux 分发版独立管理自身的配置。 若要查看特定于分发版的命令,请运行 [distro.exe] /?。 例如 ubuntu /?。 列出分发版 wsl -l、wsl --list 列出可用于 WSL 的 Linux 分发版。 如果列出了某个分发版,表示该分发版已安装且可供使用。 wsl --list --all 列出所有分发版,包括当前不可用的分发版。 这些分发版可能正在安装、卸载或处于损坏状态。 wsl --list --running 列出当前正在运行的所有分发版。 设置默认分发版 默认 WSL 分布版是在命令行中运行 wsl 时运行的分发版。 wsl […]
View Details在多种情况下,你可能无法(或不想)通过 Microsoft Store 安装 WSL Linux 发行版。 具体而言,你可能运行的是不支持 Microsoft Store 或公司网络策略和/或管理员在你的环境中不允许 Microsoft Store 使用的 Windows Server 或长期服务(LTSC)桌面操作系统 SKU。 在这些情况下,虽然 WSL 本身可用,但如果你无法访问应用商店,如何下载并在 WSL 中安装 Linux 发行版? 注意:不允许在 Windows 10 S 模式上运行命令行 shell 环境,包括 Cmd、PowerShell 和 Linux/WSL 发行版。 存在此限制是为了确保模式提供的完整性和安全性目标:阅读此文章了解详细信息。 下载发行版 如果 Microsoft Store 应用不可用,则可以通过单击以下链接下载并手动安装 Linux 发行版: Ubuntu 18.04 Ubuntu 18.04 ARM Ubuntu 16.04 Debian GNU/Linux Kali Linux OpenSUSE Leap 42 SUSE Linux Enterprise Server 12 Fedora Remix for WSL 这将导致 <distro>.appx 包下载到你选择的文件夹。 按照安装说明安装下载的发行版。 通过命令行下载发行版 如果愿意,也可以通过命令行下载首选的发行版: 使用 PowerShell 下载 若要使用 PowerShell 下载发行版,请使用WebRequest cmdlet。 下面是下载 Ubuntu 16.04 的示例说明。 PowerShell复制
|
1 2 |
<span class="hljs-pscommand">Invoke-WebRequest</span><span class="hljs-parameter"> -Uri</span> https://aka.ms/<span class="hljs-pscommand">wsl-ubuntu</span>-<span class="hljs-number">1604</span><span class="hljs-parameter"> -OutFile</span> Ubuntu.appx<span class="hljs-parameter"> -UseBasicParsing</span> |
提示 如果下载需要很长时间,请通过设置 $ProgressPreference = 'SilentlyContinue' 来关闭进度栏。 使用卷下载 Windows 10 春季2018更新(或更高版本)包含可从命令行调用 web […]
View Details最近换了工作,其中Webapi这块没有文档,之前有了解过Swagger借此机会好好整理下常用的地方分享给有需要的小伙伴。 概述: 1.swagger 引用 2.swagger 问题1.action 方法名称相同处理 3.swagger 问题2.序列化出来的JSON NULL 值处理 4. 汉化及controller说明 5. 统一返回HttpResponseMessage 返回类型 指定 6. 自定义 HTTP Header (oauth2.0 请求) 7.请求示例remarks 1.swagger 引用 第一步: 第二步:修改SwaggerConfig.cs 如 api 版本号,title 第三步:创建项目XML注释文档 右键项目→属性→生成→选中下方的 "XML文档文件" 然后保存 配置启用: c.IncludeXmlComments(string.Format("{0}/bin/BjxWebApis.XML",System.AppDomain.CurrentDomain.BaseDirectory)); 第四步:启动项目 地址:http://localhost:58303/swagger 哈哈 成功了,不对这个是最终效果,下面一步一步来实现吧。 2.swagger 问题1.action 方法名称相同处理 根据错误提示 很快发现 某位大神 同样的接口名 传递了不同参数,导致了这个错误,解决方式: c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First()); 问题解决了 进行下一步 3.swagger 问题2.序列化出来的JSON NULL 值处理 先上图 等了好半天 一直不出来 打开F12一看原来有错,万能的网友帮了我,原来问题出在http://localhost:58303/swagger/docs/v1这个JSON资源上面, 序列化出来的JSON,包含了为NULL的字段,导致swagger-ui-min-js出现异常。 进一步分析是因为我项目使用的newtonsoft.json这个库的配置导致,应该忽略为NULL的字段, 对应解决办法如图: settings.NullValueHandling = NullValueHandling.Ignore; 问题解决了 开心 继续… 4. 汉化及controller说明 看图:咦 怎么控制器没有说明,这个和汉化一起说吧 第一步:定义一个provider实现ISwaggerProvider接口 包含了缓存 名:SwaggerCacheProvider 代码:
|
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
/// <summary> /// swagger显示控制器的描述 /// </summary> public class SwaggerCacheProvider : ISwaggerProvider { private readonly ISwaggerProvider _swaggerProvider; private static ConcurrentDictionary<string, SwaggerDocument> _cache =new ConcurrentDictionary<string, SwaggerDocument>(); private readonly string _xml; /// <summary> /// /// </summary> /// <param name="swaggerProvider"></param> /// <param name="xml">xml文档路径</param> public SwaggerCacheProvider(ISwaggerProvider swaggerProvider,string xml) { _swaggerProvider = swaggerProvider; _xml = xml; } public SwaggerDocument GetSwagger(string rootUrl, string apiVersion) { var cacheKey = string.Format("{0}_{1}", rootUrl, apiVersion); SwaggerDocument srcDoc = null; //只读取一次 if (!_cache.TryGetValue(cacheKey, out srcDoc)) { srcDoc = _swaggerProvider.GetSwagger(rootUrl, apiVersion); srcDoc.vendorExtensions = new Dictionary<string, object> { { "ControllerDesc", GetControllerDesc() } }; _cache.TryAdd(cacheKey, srcDoc); } return srcDoc; } /// <summary> /// 从API文档中读取控制器描述 /// </summary> /// <returns>所有控制器描述</returns> public ConcurrentDictionary<string, string> GetControllerDesc() { string xmlpath = _xml; ConcurrentDictionary<string, string> controllerDescDict = new ConcurrentDictionary<string, string>(); if (File.Exists(xmlpath)) { XmlDocument xmldoc = new XmlDocument(); xmldoc.Load(xmlpath); string type = string.Empty, path = string.Empty, controllerName = string.Empty; string[] arrPath; int length = -1, cCount = "Controller".Length; XmlNode summaryNode = null; foreach (XmlNode node in xmldoc.SelectNodes("//member")) { type = node.Attributes["name"].Value; if (type.StartsWith("T:")) { //控制器 arrPath = type.Split('.'); length = arrPath.Length; controllerName = arrPath[length - 1]; if (controllerName.EndsWith("Controller")) { //获取控制器注释 summaryNode = node.SelectSingleNode("summary"); string key = controllerName.Remove(controllerName.Length - cCount, cCount); if (summaryNode != null && !string.IsNullOrEmpty(summaryNode.InnerText) && !controllerDescDict.ContainsKey(key)) { controllerDescDict.TryAdd(key, summaryNode.InnerText.Trim()); } } } } } return controllerDescDict; } } |
第二步:定义一个JS文件,做成嵌入资源,这个js文件的功能主要有两个,一个是汉化,另一个就是在界面上显示控制器的描述文字
|
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
'use strict'; window.SwaggerTranslator = { _words: [], translate: function () { var $this = this; $('[data-sw-translate]').each(function () { $(this).html($this._tryTranslate($(this).html())); $(this).val($this._tryTranslate($(this).val())); $(this).attr('title', $this._tryTranslate($(this).attr('title'))); }); }, setControllerSummary: function () { try { console.log($("#input_baseUrl").val()); $.ajax({ type: "get", async: true, url: $("#input_baseUrl").val(), dataType: "json", success: function (data) { var summaryDict = data.ControllerDesc; console.log(summaryDict); var id, controllerName, strSummary; $("#resources_container .resource").each(function (i, item) { id = $(item).attr("id"); if (id) { controllerName = id.substring(9); try { strSummary = summaryDict[controllerName]; if (strSummary) { $(item).children(".heading").children(".options").first().prepend('<li class="controller-summary" style="color:green;" title="' + strSummary + '">' + strSummary + '</li>'); } } catch (e) { console.log(e); } } }); } }); }catch(e) { console.log(e); } }, _tryTranslate: function (word) { return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word; }, learn: function (wordsMap) { this._words = wordsMap; } }; /* jshint quotmark: double */ window.SwaggerTranslator.learn({ "Warning: Deprecated": "警告:已过时", "Implementation Notes": "实现备注", "Response Class": "响应类", "Status": "状态", "Parameters": "参数", "Parameter": "参数", "Value": "值", "Description": "描述", "Parameter Type": "参数类型", "Data Type": "数据类型", "Response Messages": "响应消息", "HTTP Status Code": "HTTP状态码", "Reason": "原因", "Response Model": "响应模型", "Request URL": "请求URL", "Response Body": "响应体", "Response Code": "响应码", "Response Headers": "响应头", "Hide Response": "隐藏响应", "Headers": "头", "Try it out!": "试一下!", "Show/Hide": "显示/隐藏", "List Operations": "显示操作", "Expand Operations": "展开操作", "Raw": "原始", "can't parse JSON. Raw result": "无法解析JSON. 原始结果", "Model Schema": "模型架构", "Model": "模型", "apply": "应用", "Username": "用户名", "Password": "密码", "Terms of service": "服务条款", "Created by": "创建者", "See more at": "查看更多:", "Contact the developer": "联系开发者", "api version": "api版本", "Response Content Type": "响应Content Type", "fetching resource": "正在获取资源", "fetching resource list": "正在获取资源列表", "Explore": "浏览", "Show Swagger Petstore Example Apis": "显示 Swagger Petstore 示例 Apis", "Can't read from server. It may not have the appropriate access-control-origin settings.": "无法从服务器读取。可能没有正确设置access-control-origin。", "Please specify the protocol for": "请指定协议:", "Can't read swagger JSON from": "无法读取swagger JSON于", "Finished Loading Resource Information. Rendering Swagger UI": "已加载资源信息。正在渲染Swagger UI", "Unable to read api": "无法读取api", "from path": "从路径", "server returned": "服务器返回" }); $(function () { window.SwaggerTranslator.translate(); window.SwaggerTranslator.setControllerSummary(); }); |
[…]
View Details|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//地址 string _url = "https://www.dXXXayup.ink/api/User/Login"; //json参数 string jsonParam = "{ phonenumber:\"18665885202\",pwd:\"tsp\"}"; var request = (HttpWebRequest)WebRequest.Create(_url); request.Method = "POST"; request.ContentType = "application/json;charset=UTF-8"; byte[] byteData = Encoding.UTF8.GetBytes(jsonParam); int length = byteData.Length; request.ContentLength = length; Stream writer = request.GetRequestStream(); writer.Write(byteData, 0, length); writer.Close(); var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding("utf-8")).ReadToEnd(); MessageBox.Show(responseString.ToString()); |
View Details
1、普通索引 mysql>ALTER TABLE table_name ADD INDEX index_name ( column ) 普通索引(由关键字KEY或INDEX定义的索引)的唯一任务是加快对数据的访问速度。因此,应该只为那些最经常出现在查询条件(WHEREcolumn=)或排序条件(ORDERBYcolumn)中的数据列创建索引。只要有可能,就应该选择一个数据最整齐、最紧凑的数据列(如一个整数类型的数据列)来创建索引。 2、唯一索引 mysql>ALTER TABLE table_name ADD UNIQUE ( column ) 普通索引允许被索引的数据列包含重复的值。比如说,因为人有可能同名,所以同一个姓名在同一个“员工个人资料”数据表里可能出现两次或更多次。 如果能确定某个数据列将只包含彼此各不相同的值,在为这个数据列创建索引的时候就应该用关键字UNIQUE把它定义为一个唯一索引。这么做的好处:一是简化了MySQL对这个索引的管理工作,这个索引也因此而变得更有效率;二是MySQL会在有新记录插入数据表时,自动检查新记录的这个字段的值是否已经在某个记录的这个字段里出现过了;如果是,MySQL将拒绝插入那条新记录。也就是说,唯一索引可以保证数据记录的唯一性。事实上,在许多场合,人们创建唯一索引的目的往往不是为了提高访问速度,而只是为了避免数据出现重复。 3、主索引 mysql>ALTER TABLE table_name ADD PRIMARY KEY ( column ) 在前面已经反复多次强调过:必须为主键字段创建一个索引,这个索引就是所谓的“主索引”。主索引与唯一索引的唯一区别是:前者在定义时使用的关键字是PRIMARY而不是UNIQUE。 4、外键索引 mysql>ALTER TABLE table_name ADD FULLTEXT ( column) 如果为某个外键字段定义了一个外键约束条件,MySQL就会定义一个内部索引来帮助自己以最有效率的方式去管理和使用外键约束条件。 5、复合索引 mysql>ALTER TABLE table_name ADD INDEX index_name ( column1, column2, column3 ) 索引可以覆盖多个数据列,如像INDEX(columnA,columnB)索引。这种索引的特点是MySQL可以有选择地使用一个这样的索引。如果查询操作只需要用到columnA数据列上的一个索引,就可以使用复合索引INDEX(columnA,columnB)。不过,这种用法仅适用于在复合索引中排列在前的数据列组合。比如说,INDEX(A,B,C)可以当做A或(A,B)的索引来使用,但不能当做B、C或(B,C)的索引来使用。 6、索引的长度 在为CHAR和VARCHAR类型的数据列定义索引时,可以把索引的长度限制为一个给定的字符个数(这个数字必须小于这个字段所允许的最大字符个数)。这么做的好处是可以生成一个尺寸比较小、检索速度却比较快的索引文件。在绝大多数应用里,数据库中的字符串数据大都以各种各样的名字为主,把索引的长度设置为10~15个字符已经足以把搜索范围缩小到很少的几条数据记录了。在为BLOB和TEXT类型的数据列创建索引时,必须对索引的长度做出限制;MySQL所允许的最大索引全文索引文本字段上的普通索引只能加快对出现在字段内容最前面的字符串(也就是字段内容开头的字符)进行检索操作。如果字段里存放的是由几个、甚至是多个单词构成的较大段文字,普通索引就没什么作用了。这种检索往往以的形式出现,这对MySQL来说很复杂,如果需要处理的数据量很大,响应时间就会很长。 这类场合正是全文索引(full-textindex)可以大显身手的地方。在生成这种类型的索引时,MySQL将把在文本中出现的所有单词创建为一份清单,查询操作将根据这份清单去检索有关的数据记录。全文索引即可以随数据表一同创建,也可以等日后有必要时再使用下面这条命令添加: ALTERTABLEtablenameADDFULLTEXT(column1,column2)有了全文索引,就可以用SELECT查询命令去检索那些包含着一个或多个给定单词的数据记录了。下面是这类查询命令的基本语法: SELECT*FROMtablename WHEREMATCH(column1,column2)AGAINST(‘word1′,’word2′,’word3’) 上面这条命令将把column1和column2字段里有word1、word2和word3的数据记录全部查询出来。 from:https://www.cnblogs.com/interdrp/p/8031087.html
View Details同事说decimal转换不了,仔细看了,没有问题,如图: 红色都是有问题的,肉眼是看不出任何问题的。 用正则也把空白,常用的回车换行符什么的都替换,依然转换不了。 后来,我打印一下字串的长度,发现总是比肉眼观察到的多一位,于是就复制了这个字符,直接替换,转换成功! 来看看下面的代码:
|
1 2 3 4 5 6 7 |
string tt1 = "941501"; string tt3 = "941501"; // 你没看错,以上两个值是不相等的,在tt1的后面有一个神秘的空白字符。 decimal.TryParse(tt1.Replace("", ""), out var tt2); // 别以为我是把空替换为空,前面的双引号里是有个看不见的字符的 MessageBox.Show(tt2.ToString(CultureInfo.InvariantCulture)+"\n"+(tt1.Length+"-"+tt3.Length)); |
通过转码,神秘字符转码后: UrlEncode:%E2%80%AC 十六进制:2623383233363B
View Details问题 提示丢失 VCRUNTIME140.DLL 解决方案 简介分析:建立装时,需要C++应用的必要组件, 去微软官网下载安装程序,安装就可以了。有64位版和32位版,根据计算机配置进行下载,下面是下载链接: 64位版下载地址:http://download.microsoft.com/download/9/E/1/9E1FA77A-9E95-4F3D-8BE1-4D2D0C947BA2/enu_INREL/vcredistd14x64/vc_redist.x64.exe 32位版下载地址:http://download.microsoft.com/download/9/E/1/9E1FA77A-9E95-4F3D-8BE1-4D2D0C947BA2/enu_INREL/vcredistd14x86/vc_redist.x86.exe from:https://blog.csdn.net/qq_41204464/article/details/93408593
View DetailsWeb前端开发技术栈 浏览器 Internet Explorer Chrome Firefox Safari Opera Edge Netscape 协议 HTTP/1.1 链接 会话 授权 请求 响应 HTTP/2 压缩 打包 服务器端推送 WebSocket Web三剑客 HTML (HyperText Markup Language) CSS (Cascading Style Sheets) JavaScript 标准 W3C HTML CSS XHTML XML 核心概念 HTML DOM Element Attribute JavaScript Prototype Scope Closure JSON (JavaSript Object Notation) AJAX (Asynchronous JavaScript and XML) CSS Selector Priority Specificity Box Model 渲染引擎 Trident (IE) Blink / prev. WebKit (Chrome) Gecko (Firefox) WebKit (Safari) Blink / prev. Presto (Opera) EdgeHTML (Edge) 脚本引擎 JScript (IE8- / ASP) Chakra (IE9+ […]
View Details