月度归档:2017年09月

C# LRU

 

using System.Collections.Generic;
using System.Threading;

namespace Lru
{
    public class LRUCache<TKey, TValue>
    {
        const int DEFAULT_CAPACITY = 255;

        int _capacity;
        ReaderWriterLockSlim _locker;
        IDictionary<TKey, TValue> _dictionary;
        LinkedList _linkedList;

        public LRUCache() : this(DEFAULT_CAPACITY) { }

        public LRUCache(int capacity)
        {
            _locker = new ReaderWriterLockSlim();
            _capacity = capacity > 0 ? capacity : DEFAULT_CAPACITY;
            _dictionary = new Dictionary<TKey, TValue>();
            _linkedList = new LinkedList();
        }

        public void Set(TKey key, TValue value)
        {
            _locker.EnterWriteLock();
            try
            {
                _dictionary[key] = value;
                _linkedList.Remove(key);
                _linkedList.AddFirst(key);
                if (_linkedList.Count > _capacity)
                {
                    _dictionary.Remove(_linkedList.Last.Value);
                    _linkedList.RemoveLast();
                }
            }
            finally { _locker.ExitWriteLock(); }
        }

        public bool TryGet(TKey key, out TValue value)
        {
            _locker.EnterUpgradeableReadLock();
            try
            {
                bool b = _dictionary.TryGetValue(key, out value);
                if (b)
                {
                    _locker.EnterWriteLock();
                    try
                    {
                        _linkedList.Remove(key);
                        _linkedList.AddFirst(key);
                    }
                    finally { _locker.ExitWriteLock(); }
                }
                return b;
            }
            catch { throw; }
            finally { _locker.ExitUpgradeableReadLock(); }
        }

        public bool ContainsKey(TKey key)
        {
            _locker.EnterReadLock();
            try
            {
                return _dictionary.ContainsKey(key);
            }
            finally { _locker.ExitReadLock(); }
        }

        public int Count
        {
            get
            {
                _locker.EnterReadLock();
                try
                {
                    return _dictionary.Count;
                }
                finally { _locker.ExitReadLock(); }
            }
        }

        public int Capacity
        {
            get
            {
                _locker.EnterReadLock();
                try
                {
                    return _capacity;
                }
                finally { _locker.ExitReadLock(); }
            }
            set
            {
                _locker.EnterUpgradeableReadLock();
                try
                {
                    if (value > 0 && _capacity != value)
                    {
                        _locker.EnterWriteLock();
                        try
                        {
                            _capacity = value;
                            while (_linkedList.Count > _capacity)
                            {
                                _linkedList.RemoveLast();
                            }
                        }
                        finally { _locker.ExitWriteLock(); }
                    }
                }
                finally { _locker.ExitUpgradeableReadLock(); }
            }
        }

        public ICollection Keys
        {
            get
            {
                _locker.EnterReadLock();
                try
                {
                    return _dictionary.Keys;
                }
                finally { _locker.ExitReadLock(); }
            }
        }

        public ICollection Values
        {
            get
            {
                _locker.EnterReadLock();
                try
                {
                    return _dictionary.Values;
                }
                finally { _locker.ExitReadLock(); }
            }
        }
    }
}

 

来源:http://www.itwendao.com/article/detail/243752.html

MySQL 全文索引(fulltext index)

1.创建全文索引(FullText index)

旧版的MySQL的全文索引只能用在MyISAM表格的char、varchar和text的字段上。

不过新版的MySQL5.6.24上InnoDB引擎也加入了全文索引,所以具体信息要随时关注官网,
1.1. 创建表的同时创建全文索引

CREATE TABLE article (
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT(title, body)
) TYPE=MYISAM;

1.2.通过 alter table 的方式来添加

ALTER TABLE `student` ADD FULLTEXT INDEX ft_stu_name (`name`) #ft_stu_name是索引名,可以随便起

或者:ALTER TABLE `student` ADD FULLTEXT ft_stu_name (`name`)

1.3. 直接通过create index的方式

CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`)

也可以在创建索引的时候指定索引的长度:

CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`(20))

2. 删除全文索引
2.1. 直接使用 drop index(注意:没有 drop fulltext index 这种用法)

DROP INDEX full_idx_name ON tommy.girl ;
2.2. 使用 alter table的方式

ALTER TABLE tommy.girl DROP INDEX ft_email_abcd;

3.使用全文索引

跟普通索引稍有不同

使用全文索引的格式: MATCH (columnName) AGAINST ('string')

eg:

SELECT * FROM `student` WHERE MATCH(`name`) AGAINST('聪')

当查询多列数据时:

建议在此多列数据上创建一个联合的全文索引,否则使用不了索引的。

SELECT * FROM `student` WHERE MATCH(`name`,`address`) AGAINST('聪 广东')
3.1. 使用全文索引需要注意的是:(基本单位是词)

分词,全文索引以词为基础的,MySQL默认的分词是所有非字母和数字的特殊符号都是分词符(外国人嘛)

这里推荐一篇文章:利用mysql的全文索引实现模糊查询

3.2. MySQL中与全文索引相关的几个变量:

使用命令:mysql> SHOW VARIABLES LIKE 'ft%'; #ft就是FullText的简写

ft_boolean_syntax + -><()~*:""&| #改变IN BOOLEAN MODE的查询字符,不用重新启动MySQL也不用重建索引 ft_min_word_len 4 #最短的索引字符串,默认值为4,(通常改为1)修改后必须重建索引文件 重新建立索引命令:repair table tablename quick ft_max_word_len 84 #最长的索引字符串,默认值为84,修改后必须重建索引文件 ft_query_expansion_limit 20 #查询括展时取最相关的几个值用作二次查询 ft_stopword_file (built-in) #全文索引的过滤词文件,具体可以参考:MySQL全文检索中不进行全文索引默认过滤词 特别注意:50%的门坎限制(当查询结果很多,几乎所有记录都有,或者极少的数据,都有可能会返回非所期望的结果) -->可用IN BOOLEAN MODE即可以避开50%的限制。

此时使用全文索引的格式就变成了: SELECT * FROM `student` WHERE MATCH(`name`) AGAINST('聪' IN BOOLEAN MODE)

更多内容请参考:MySQL中的全文检索(1)

4. ft_boolean_syntax (+ -><()~*:""&|)使用的例子: 4.1 + : 用在词的前面,表示一定要包含该词,并且必须在开始位置。 eg: +Apple 匹配:Apple123, "tommy, Apple" 4.2 - : 不包含该词,所以不能只用「-yoursql」这样是查不到任何row的,必须搭配其他语法使用。 eg: MATCH (girl_name) AGAINST ('-林志玲 +张筱雨') 匹配到: 所有不包含林志玲,但包含张筱雨的记录 4.3. 空(也就是默认情况),表示可选的,包含该词的顺序较高。 例子: apple banana 找至少包含上面词中的一个的记录行 +apple +juice 两个词均在被包含 +apple macintosh 包含词 “apple”,但是如果同时包含 “macintosh”,它的排列将更高一些 +apple -macintosh 包含 “apple” 但不包含 “macintosh” 4.4. > :提高该字的相关性,查询的结果会排在比较靠前的位置。
4.5.< :降低相关性,查询的结果会排在比较靠后的位置。 例子:4.5.1.先不使用 >< select * from tommy.girl where match(girl_name) against('张欣婷' in boolean mode); 可以看到完全匹配的排的比较靠前 4.5.2. 单独使用 >

select * from tommy.girl where match(girl_name) against('张欣婷 >李秀琴' in boolean mode);

使用了>的李秀琴马上就排到最前面了

4.5.3. 单独使用 <

select * from tommy.girl where match(girl_name) against('张欣婷 <不是人' in boolean mode);

看到没,不是人也排到最前面了,这里使用的可是 < 哦,说好的降低相关性呢,往下看吧。 4.5.4.同时使用>< select * from tommy.girl where match(girl_name) against('张欣婷 >李秀琴 <练习册 <不是人>是个鬼' in boolean mode);

到这里终于有答案了,只要使用了 ><的都会往前排,而且>的总是排在<的前面 小结一下:1. 只要使用 ><的总比没用的 靠前; 2. 使用 >的一定比 <的排的靠前 (这就符合相关性提高和降低); 3. 使用同一类的,使用的越早,排的越前。 4.6. ( ):可以通过括号来使用字条件。 eg: +aaa +(>bbb <ccc) // 找到有aaa和bbb和ccc,aaa和bbb,或者aaa和ccc(因为bbb,ccc前面没有+,所以表示可有可无), 然后 aaa&bbb > aaa&bbb&ccc > aaa&ccc
4.7. ~ :将其相关性由正转负,表示拥有该字会降低相关性,但不像「-」将之排除,只是排在较后面。

eg: +apple ~macintosh 先匹配apple,但如果同时包含macintosh,就排名会靠后。
4.8. * :通配符,这个只能接在字符串后面。

MATCH (girl_name) AGAINST ('+*ABC*') #错误,不能放前面

MATCH (girl_name) AGAINST ('+张筱雨*') #正确
4.9. " " :整体匹配,用双引号将一段句子包起来表示要完全相符,不可拆字。

eg: "tommy huang" 可以匹配 tommy huang xxxxx 但是不能匹配 tommy is huang。
5.补充:Windows下无法修改 ft_min_word_len的情况,
5. 1. 使用cmd打开 services.msc,

找到你的 MySQL服务,右键Properties,找到你的my.ini所在的路径

5.2. 停止MySQL,在my.ini中增加 ft_min_word_len = 1,重启MySQL,

然后使用命令 show variables like 'ft_min_word_len'; 查看是否生效了

LDAP

1. LDAP简介

LDAP(轻量级目录访问协议,Lightweight Directory Access Protocol)是实现提供被称为目录服务的信息服务。目录服务是一种特殊的数据库系统,其专门针对读取,浏览和搜索操作进行了特定的优化。目录一般用来包含描述性的,基于属性的信息并支持精细复杂的过滤能力。目录一般不支持通用数据库针对大量更新操作操作需要的复杂的事务管理或回卷策略。而目录服务的更新则一般都非常简单。这种目录可以存储包括个人信息、web链结、jpeg图像等各种信息。为了访问存储在目录中的信息,就需要使用运行在TCP/IP 之上的访问协议—LDAP。

LDAP目录中的信息是是按照树型结构组织,具体信息存储在条目(entry)的数据结构中。条目相当于关系数据库中表的记录;条目是具有区别名DN (Distinguished Name)的属性(Attribute),DN是用来引用条目的,DN相当于关系数据库表中的关键字(Primary Key)。属性由类型(Type)和一个或多个值(Values)组成,相当于关系数据库中的字段(Field)由字段名和数据类型组成,只是为了方便检索的需要,LDAP中的Type可以有多个Value,而不是关系数据库中为降低数据的冗余性要求实现的各个域必须是不相关的。LDAP中条目的组织一般按照地理位置和组织关系进行组织,非常的直观。LDAP把数据存放在文件中,为提高效率可以使用基于索引的文件数据库,而不是关系数据库。类型的一个例子就是mail,其值将是一个电子邮件地址。

LDAP的信息是以树型结构存储的,在树根一般定义国家(c=CN)或域名(dc=com),在其下则往往定义一个或多个组织 (organization)(o=Acme)或组织单元(organizational units) (ou=People)。一个组织单元可能包含诸如所有雇员、大楼内的所有打印机等信息。此外,LDAP支持对条目能够和必须支持哪些属性进行控制,这是有一个特殊的称为对象类别(objectClass)的属性来实现的。该属性的值决定了该条目必须遵循的一些规则,其规定了该条目能够及至少应该包含哪些属性。例如:inetorgPerson对象类需要支持sn(surname)和cn(common name)属性,但也可以包含可选的如邮件,电话号码等属性。

2. LDAP简称对应

o– organization(组织-公司)
ou – organization unit(组织单元-部门)
c - countryName(国家)
dc - domainComponent(域名)
sn – suer name(真实名称)
cn - common name(常用名称)

3. 目录设计

设计目录结构是LDAP最重要的方面之一。下面我们将通过一个简单的例子来说明如何设计合理的目录结构。该例子将通过Netscape地址薄来访文。假设有一个位于美国US(c=US)而且跨越多个州的名为Acme(o=Acme)的公司。Acme希望为所有的雇员实现一个小型的地址薄服务器。

我们从一个简单的组织DN开始:

dn: o=Acme, c=US

Acme所有的组织分类和属性将存储在该DN之下,这个DN在该存储在该服务器的目录是唯一的。Acme希望将其雇员的信息分为两类:管理者(ou= Managers)和普通雇员(ou=Employees),这种分类产生的相对区别名(RDN,relative distinguished names。表示相对于顶点DN)就shi :

dn: ou=Managers, o=Acme, c=US
dn: ou=Employees, o=Acme, c=US

在下面我们将会看到分层结构的组成:顶点是US的Acme,下面是管理者组织单元和雇员组织单元。因此包括Managers和Employees的DN组成为:

dn: cn=Jason H. Smith, ou=Managers, o=Acme, c=US
dn: cn=Ray D. Jones, ou=Employees, o=Acme, c=US
dn: cn=Eric S. Woods, ou=Employees, o=Acme, c=US

为了引用Jason H. Smith的通用名(common name )条目,LDAP将采
用cn=Jason H. Smith的RDN。
然后将前面的父条目结合在一起就形成如下的树型结构:

cn=Jason H. Smith
+ ou=Managers
+ o=Acme
+ c=US
-> dn: cn=Jason H. Smith,ou=Managers,o=Acme,c=US

现在已经定义好了目录结构,下一步就需要导入目录信息数据。目录信息数据将被存放在LDIF文件中,其是导入目录信息数据的默认存放文件。用户可以方便的编写Perl脚本来从例如/etc/passwd、NIS等系统文件中自动创建LDIF文件。

下面的实例保存目录信息数据为testdate.ldif文件,该文件的格式说明将可以在man ldif中得到。

在添加任何组织单元以前,必须首先定义Acme DN:

dn: o=Acme, c=US,
objectClass: organization

这里o属性是必须的

o: Acme

下面是管理组单元的DN,在添加任何管理者信息以前,必须先定义该条目。

dn: ou=Managers, o=Acme, c=US
objectClass: organizationalUnit

这里ou属性是必须的。

ou: Managers

第一个管理者DN:

dn: cn=Jason H. Smith, ou=Managers, o=Acme, c=US
objectClass: inetOrgPerson

cn和sn都是必须的属性:

cn: Jason H. Smith
sn: Smith

但是还可以定义一些可选的属性:

telephoneNumber: 111-222-9999
mail: headhauncho@acme.com
localityName: Houston

可以定义另外一个组织单元:

dn: ou=Employees, o=Acme, c=US
objectClass: organizationalUnit
ou: Employees

并添加雇员信息如下:

dn: cn=Ray D. Jones, ou=Employees, o=Acme, c=US
objectClass: inetOrgPerson
cn: Ray D. Jones
sn: Jones
telephoneNumber: 444-555-6767
mail: jonesrd@acme.com
localityName: Houston
dn: cn=Eric S. Woods, ou=Employees, o=Acme, c=US
objectClass: inetOrgPerson
cn: Eric S. Woods
sn: Woods
telephoneNumber: 444-555-6768
mail: woodses@acme.com
localityName: Houston

4. 配置OpenLDAP

本文实践了在 Windows 下安装配 openldap,并添加一个条目,LdapBrowser 浏览,及 Java 程序连接 openldap 的全过程。

1. 下载安装 openldap for windows,当前版本2.2.29下载地址:http://download.bergmans.us/openldap/openldap-2.2.29/openldap-2.2.29-db-4.3.29-openssl-0.9.8a-win32_Setup.exe

相关链接:http://lucas.bergmans.us/hacks/openldap/
安装很简单,一路 next 即可,假设我们安装在 c:\openldap

2. 配置 openldap,编辑 sldap.conf 文件

1) 打开 c:\openldap\sldap.conf,找到
include  C:/openldap/etc/schema/core.schema,在它后面添
include  C:/openldap/etc/schema/cosine.schema
include  C:/openldap/etc/schema/inetorgperson.schema

接下来的例子只需要用到以上三个 schema,当然,如果你觉得需要的话,你可以把其他的 schema 全部添加进来
include  C:/openldap/etc/schema/corba.schema
include  C:/openldap/etc/schema/dyngroup.schema
include  C:/openldap/etc/schema/java.schema
include  C:/openldap/etc/schema/misc.schema
include  C:/openldap/etc/schema/nis.schema
include  C:/openldap/etc/schema/openldap.schema

2) 还是在 sldap.conf 文件中,找到

suffix  "dc=my-domain,dc=com"
rootdn  "cn=Manager,dc=my-domain,dc=com"

把这两行改为
suffix "o=teemlink,c=cn"
rootdn "cn=Manager,o=teemlink,dc=cn"

suffix 就是看自己如何定义了,后面步骤的 ldif 文件就必须与它定义了。还要注意到这个配置文件中有一个 rootpw  secret,这个 secret 是 cn=Manager 的密码,以后会用到,不过这里是明文密码,你可以用命令: slappasswd -h {MD5} -s secret 算出加密的密码 {MD5}Xr4ilOzQ4PCOq3aQ0qbuaQ== 取代配置中的 secret。

3. 启动 openldap

CMD 进入到 c:\openldap 下,运行命令 sldapd -d 1
用可以看到控制台下打印一片信息,openldap 默认是用的 Berkeley DB 数据库存储目录数据的。

4. 建立条目,编辑导入 ldif 文件

1) 新建一个 ldif(LDAP Data Interchanged Format) 文件(纯文本格式),例如 test.ldif,文件内容如下:

dn: o=teemlink
objectclass: top
objectclass: organization
o: develop

2) 执行命令:ldapadd -l test.ldif

5. 使用LDAP Browser进行访问
5.1安装LDAP Browser2.6软件,进行如下操作:

5.2显示效果

5. Java操作LDAP

5.1 用JNDI进访问

package cn.myapps.test;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

public class LdapTest {
    public void JNDILookup() {
        String root = "o=teemlink,c=cn";
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, "ldap://192.168.0.30/" + root);
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        env.put(Context.SECURITY_PRINCIPAL, "cn=Nicholas,ou=产品,o=teemlink,c=cn");
        env.put(Context.SECURITY_CREDENTIALS, "123456");
        DirContext ctx = null;

        try {
            ctx = new InitialDirContext(env);
            Attributes attrs = ctx.getAttributes("cn=Nicholas,ou=产品");
            System.out.println("Last Name: " + attrs.get("sn").get());
            System.out.println("认证成功");
        } catch (javax.naming.AuthenticationException e) {
            e.printStackTrace();
            System.out.println("认证失败");
        } catch (Exception e) {
            System.out.println("认证出错:");
            e.printStackTrace();
        }
        if (ctx != null) {
            try {
                ctx.close();
            } catch (NamingException e) {
                // ignore
            }
        }
    }

    public static void main(String[] args) {
        LdapTest LDAPTest = new LdapTest();
        LDAPTest.JNDILookup();
    }
}

5.2 用JLDAP进访问

访问地址:http://www.openldap.org/jldap/ 并下载相关lib

import com.novell.ldap.*;

import java.io.UnsupportedEncodingException;

public class List

{

    public static void main(String[] args)

    {
        int ldapPort = LDAPConnection.DEFAULT_PORT;
        int searchScope = LDAPConnection.SCOPE_ONE;
        int ldapVersion = LDAPConnection.LDAP_V3;
        boolean attributeOnly = false;
        String attrs[] = null;
        String ldapHost = "192.168.0.30";
        String loginDN = "cn=Manager,o=teemlink,c=cn";
        String password = "secret";
        String searchBase = "ou=develop,o=teemlink,c=cn";
        String searchFilter = "objectClass=*";

        LDAPConnection lc = new LDAPConnection();
        try {
            // connect to the server
            lc.connect(ldapHost, ldapPort);

            // bind to the server
            lc.bind(ldapVersion, loginDN, password.getBytes("UTF8"));

            LDAPSearchResults searchResults =

            lc.search(searchBase, // container to search
                    searchScope, // search scope
                    searchFilter, // search filter
                    attrs, // "1.1" returns entry name only
                    attributeOnly); // no attributes are returned

            // print out all the objects
            while (searchResults.hasMore()) {
                LDAPEntry nextEntry = null;
                try {
                    nextEntry = searchResults.next();
                    System.out.println("\n" + nextEntry.getDN());
                    System.out.println(nextEntry.getAttributeSet());
                } catch (LDAPException e) {
                    System.out.println("Error: " + e.toString());
                    // Exception is thrown, go for next entry
                    continue;
                }
            }

            // disconnect with the server
            lc.disconnect();

        } catch (LDAPException e) {
            System.out.println("Error: " + e.toString());
        } catch (UnsupportedEncodingException e) {
            System.out.println("Error: " + e.toString());
        }
        System.exit(0);
    }
}

5.3 用JDBC-LDAP进访问

访问地址:http://www.openldap.org/jdbcldap/ 并下载相关lib

package jdbcldap;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JdbcLdap {

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        Class.forName("com.octetstring.jdbcLdap.sql.JdbcLdapDriver");
        String ldapConnectString = "jdbc:ldap://192.168.0.30/o=teemlink,c=cn?SEARCH_SCOPE:=subTreeScope";
        Connection con = DriverManager.getConnection(ldapConnectString, "cn=Manager,o=teemlink,c=cn", "secret");

        String sql = "SELECT * FROM ou=develop,o=teemlink,c=cn";

        Statement sat = con.createStatement();
        ResultSet rs = sta.executeQuery(sql);
        while (rs.next()) {
            System.out.println(rs.getString(1));
        }

        if (con != null)
            con.close();
    }
}

原创人员:Nicholas

来源:http://www.cnblogs.com/obpm/archive/2010/08/28/1811065.html

Links:
https://segmentfault.com/a/1190000002607140

MySQL FullText

1.创建全文索引(FullText index)

旧版的MySQL的全文索引只能用在MyISAM表格的char、varchar和text的字段上。

不过新版的MySQL5.6.24上InnoDB引擎也加入了全文索引,所以具体信息要随时关注官网,
1.1. 创建表的同时创建全文索引

CREATE TABLE article (
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
FULLTEXT(title, body)
) TYPE=MYISAM;

1.2.通过 alter table 的方式来添加

ALTER TABLE `student` ADD FULLTEXT INDEX ft_stu_name (`name`) #ft_stu_name是索引名,可以随便起

或者:ALTER TABLE `student` ADD FULLTEXT ft_stu_name (`name`)

1.3. 直接通过create index的方式

CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`)

也可以在创建索引的时候指定索引的长度:

CREATE FULLTEXT INDEX ft_email_name ON `student` (`name`(20))

2. 删除全文索引
2.1. 直接使用 drop index(注意:没有 drop fulltext index 这种用法)

DROP INDEX full_idx_name ON tommy.girl ;
2.2. 使用 alter table的方式

ALTER TABLE tommy.girl DROP INDEX ft_email_abcd;

3.使用全文索引

跟普通索引稍有不同

使用全文索引的格式: MATCH (columnName) AGAINST ('string')

eg:

SELECT * FROM `student` WHERE MATCH(`name`) AGAINST('聪')

当查询多列数据时:

建议在此多列数据上创建一个联合的全文索引,否则使用不了索引的。

SELECT * FROM `student` WHERE MATCH(`name`,`address`) AGAINST('聪 广东')

3.1. 使用全文索引需要注意的是:(基本单位是词)

分词,全文索引以词为基础的,MySQL默认的分词是所有非字母和数字的特殊符号都是分词符

3.2. MySQL中与全文索引相关的几个变量:

使用命令:mysql> SHOW VARIABLES LIKE 'ft%'; #ft就是FullText的简写

ft_boolean_syntax + -><()~*:""&| #改变IN BOOLEAN MODE的查询字符,不用重新启动MySQL也不用重建索引

ft_min_word_len 4 #最短的索引字符串,默认值为4,(通常改为1)修改后必须重建索引文件 重新建立索引命令:repair table tablename quick

ft_max_word_len 84 #最长的索引字符串,默认值为84,修改后必须重建索引文件

ft_query_expansion_limit 20 #查询括展时取最相关的几个值用作二次查询

ft_stopword_file (built-in) #全文索引的过滤词文件,具体可以参考:MySQL全文检索中不进行全文索引默认过滤词 特别注意:50%的门坎限制(当查询结果很多,几乎所有记录都有,或者极少的数据,都有可能会返回非所期望的结果) -->可用IN BOOLEAN MODE即可以避开50%的限制。

此时使用全文索引的格式就变成了: SELECT * FROM `student` WHERE MATCH(`name`) AGAINST('聪' IN BOOLEAN MODE)

4. ft_boolean_syntax (+ -><()~*:""&|) 逻辑全文搜索:

逻辑全文搜索支持下面的操作符:

+
一个领头的加号表示,该词必须出现在每个返回的记录行中。

-
一个领头的减号表示,该词必须不出现在每个返回的记录行中。

缺省的 (当既没有加号也没有负号被指定时)词是随意的,但是包含它的记录行将被排列地更高一点。这个模仿没有 IN BOOLEAN MODE 修饰词的 MATCH() ... AGAINST() 的行为。

< >
这两个操作符用于改变一个词的相似性值的基值。< 操作符减少基值,> 操作符则增加它。参看下面的示例。

( )
圆括号用于对子表达式中的词分组。

~
一个领头的否定号的作用象一个否定操作符,引起行相似性的词的基值为负的。它对标记一个噪声词很有用。一个包含这样的词的记录将被排列得低一点,但是不会被完全的排除,因为这样可以使用 - 操作符。

*
一个星号是截断操作符。不想其它的操作符,它应该被追加到一个词后,不加在前面。

""
短语,被包围在双引号""中,只匹配包含这个短语(字面上的,就好像被键入的)的记录行。

一些示例:

apple banana
找至少包含上面词中的一个的记录行
+apple +juice
... 两个词均在被包含
+apple macintosh
... 包含词 “apple”,但是如果同时包含 “macintosh”,它的排列将更高一些
+apple -macintosh
... 包含 “apple” 但不包含 “macintosh”
+apple +(>pie <strudel)
... 包含 “apple” 和 “pie”,或者包含的是 “apple” 和 “strudel” (以任何次序),但是 “apple pie” 排列得比 “apple strudel” 要高一点
apple*
... 包含 “apple”,“apples”,“applesauce” 和 “applet”
"some words"
... 可以包含 “some words of wisdom”,但不是 “some noise words”

4.1. 降低相关性例子,查询的结果会排在比较靠后的位置。
4.1.1.先不使用 ><
select * from tommy.girl where match(girl_name) against('张欣婷' in boolean mode);

完全匹配的排的比较靠前

4.1.2. 单独使用 >

select * from tommy.girl where match(girl_name) against('张欣婷 >李秀琴' in boolean mode);

使用了>的李秀琴排到最前面

4.1.3. 单独使用 <

select * from tommy.girl where match(girl_name) against('张欣婷 <不是人' in boolean mode);

看到没,不是人也排到最前面了,这里使用的可是 < 哦,说好的降低相关性呢,往下看吧。

4.1.4.同时使用><

select * from tommy.girl where match(girl_name) against('张欣婷 >李秀琴 <练习册 <不是人>是个鬼' in boolean mode);

只要使用了 ><的都会往前排,而且>的总是排在<的前面
小结:
1. 只要使用 ><的总比没用的 靠前;
2. 使用 >的一定比 <的排的靠前 (这就符合相关性提高和降低);
3. 使用同一类的,使用的越早,排的越前。

 

5.补充
Windows下无法修改 ft_min_word_len的情况,

5. 1. 使用cmd打开 services.msc,

找到你的 MySQL服务,右键Properties,找到你的my.ini所在的路径

5.2. 停止MySQL,在my.ini中增加 ft_min_word_len = 1,重启MySQL,

然后使用命令 show variables like 'ft_min_word_len'; 查看是否生效了

 

来源: http://blog.csdn.net/u011734144/article/details/52817766

 

 

5种开源协议比较

BSD开源协议

BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。

但”为所欲为”的前提当你发布使用了BSD协议的代码,或则以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件:

  1. 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。
  2. 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。
  3. 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。

BSD 代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对 商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议,因为可以完全控制这些第三方的代码,在必要的时候可以修改或者二次开发。

Apache Licence 2.0

Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似,同样鼓励代码共享和尊重原作者的著作权,同样允许代码修改,再发布(作为开源或商业软件)。需要满足的条件也和BSD类似:

  1. 需要给代码的用户一份Apache Licence
  2. 如果你修改了代码,需要再被修改的文件中说明。
  3. 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。
  4. 如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。

Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。

GPL

我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用,但不允许修改后和衍生的代 码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux,包括商业公司的linux和linux上各种各样的由个人,组织,以及商 业软件公司开发的免费软件了。

GPL协议的主要内容是只要在一个软件中使用(”使用”指类库引用,修改后的代码或者衍生代码)GPL 协议的产品,则该软件产品必须也采用GPL协议,既必须也是开源和免费。这就是所谓的”传染性”。GPL协议的产品作为一个单独的产品使用没有任何问题,还可以享受免费的优势。

由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议,对于使用GPL协议的开源代码,商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。

其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。

LGPL

LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL 允许商业软件通过类库引用(link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并 发布和销售。

但是如果修改LGPL协议的代码或者衍生,则所有修改的代码,涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源 代码很适合作为第三方类库被商业软件引用,但不适合希望以LGPL协议代码为基础,通过修改和衍生的方式做二次开发的商业软件采用。

GPL/LGPL都保障原作者的知识产权,避免有人利用开源代码复制并开发类似的产品

MIT

MIT是和BSD一样宽范的许可协议,作者只想保留版权,而无任何其他了限制.也就是说,你必须在你的发行版里包含原许可协议的声明,无论你是以二进制发布的还是以源代码发布的.

Links:

5种开源协议比较

 

 

iptables cases

#查看iptables现有规则
iptables -L -n
#先允许所有,不然有可能会杯具
iptables -P INPUT ACCEPT
#清空所有默认规则
iptables -F
#清空所有自定义规则
iptables -X
#所有计数器归0
iptables -Z
#允许来自于lo接口的数据包(本地访问)
iptables -A INPUT -i lo -j ACCEPT
#开放22端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
#开放21端口(FTP)
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
#开放80端口(HTTP)
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
#开放443端口(HTTPS)
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
#允许ping
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
#允许接受本机请求之后的返回数据 RELATED,是为FTP设置的
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#其他入站一律丢弃
iptables -P INPUT DROP
#所有出站一律绿灯
iptables -P OUTPUT ACCEPT
#所有转发一律丢弃
iptables -P FORWARD DROP

 

#如果要添加内网ip信任(接受其所有TCP请求)
iptables -A INPUT -p tcp -s 45.96.174.68 -j ACCEPT
#过滤所有非以上规则的请求
iptables -P INPUT DROP
#要封停一个IP,使用下面这条命令:
iptables -I INPUT -s ***.***.***.*** -j DROP
#要解封一个IP,使用下面这条命令:
iptables -D INPUT -s ***.***.***.*** -j DROP
IPSEC NAT 策略
iptables -I PFWanPriv -d 192.168.100.2 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 80 -d $INTERNET_ADDR -j DNAT --to-destination 192.168.100.2:80
iptables -t nat -A PREROUTING -p tcp --dport 1723 -d $INTERNET_ADDR -j DNAT --to-destination 192.168.100.2:1723
iptables -t nat -A PREROUTING -p udp --dport 1723 -d $INTERNET_ADDR -j DNAT --to-destination 192.168.100.2:1723
iptables -t nat -A PREROUTING -p udp --dport 500 -d $INTERNET_ADDR -j DNAT --to-destination 192.168.100.2:500
iptables -t nat -A PREROUTING -p udp --dport 4500 -d $INTERNET_ADDR -j DNAT --to-destination 192.168.100.2:4500

FTP服务器的NAT
iptables -I PFWanPriv -p tcp --dport 21 -d 192.168.1.22 -j ACCEPT
iptables -t nat -A PREROUTING -p tcp --dport 21 -d $INTERNET_ADDR -j DNAT --to-destination 192.168.1.22:21

只允许访问指定网址
iptables -A Filter -p udp --dport 53 -j ACCEPT
iptables -A Filter -p tcp --dport 53 -j ACCEPT
iptables -A Filter -d www.ctohome.com -j ACCEPT
iptables -A Filter -d www.guowaivps.com -j ACCEPT
iptables -A Filter -j DROP

开放一个IP的一些端口,其它都封闭
iptables -A Filter -p tcp --dport 80 -s 192.168.1.22 -d www.pconline.com.cn -j ACCEPT
iptables -A Filter -p tcp --dport 25 -s 192.168.1.22 -j ACCEPT
iptables -A Filter -p tcp --dport 109 -s 192.168.1.22 -j ACCEPT
iptables -A Filter -p tcp --dport 110 -s 192.168.1.22 -j ACCEPT
iptables -A Filter -p tcp --dport 53 -j ACCEPT
iptables -A Filter -p udp --dport 53 -j ACCEPT
iptables -A Filter -j DROP

多个端口
iptables -A Filter -p tcp -m multiport --destination-port 22,53,80,110 -s 192.168.20.3 -j REJECT

连续端口
iptables -A Filter -p tcp -m multiport --source-port 22,53,80,110 -s 192.168.20.3 -j REJECT iptables -A Filter -p tcp --source-port 2:80 -s 192.168.20.3 -j REJECT

指定时间上网
iptables -A Filter -s 10.10.10.253 -m time --timestart 6:00 --timestop 11:00 --days Mon,Tue,Wed,Thu,Fri,Sat,Sun -j DROP
iptables -A Filter -m time --timestart 12:00 --timestop 13:00 --days Mon,Tue,Wed,Thu,Fri,Sat,Sun -j ACCEPT
iptables -A Filter -m time --timestart 17:30 --timestop 8:30 --days Mon,Tue,Wed,Thu,Fri,Sat,Sun -j ACCEPT

禁止多个端口服务
iptables -A Filter -m multiport -p tcp --dport 21,23,80 -j ACCEPT

将WAN 口NAT到PC
iptables -t nat -A PREROUTING -i $INTERNET_IF -d $INTERNET_ADDR -j DNAT --to-destination 192.168.0.1

将WAN口8000端口NAT到192。168。100。200的80端口
iptables -t nat -A PREROUTING -p tcp --dport 8000 -d $INTERNET_ADDR -j DNAT --to-destination 192.168.1.22:80

MAIL服务器要转的端口
iptables -t nat -A PREROUTING -p tcp --dport 110 -d $INTERNET_ADDR -j DNAT --to-destination 192.168.1.22:110
iptables -t nat -A PREROUTING -p tcp --dport 25 -d $INTERNET_ADDR -j DNAT --to-destination 192.168.1.22:25

只允许PING 202。96。134。133,别的服务都禁止
iptables -A Filter -p icmp -s 192.168.1.22 -d 202.96.134.133 -j ACCEPT
iptables -A Filter -j DROP

禁用BT配置
iptables –A Filter –p tcp –dport 6000:20000 –j DROP

禁用QQ防火墙配置
iptables -A Filter -p udp --dport ! 53 -j DROP
iptables -A Filter -d 218.17.209.0/24 -j DROP
iptables -A Filter -d 218.18.95.0/24 -j DROP
iptables -A Filter -d 219.133.40.177 -j DROP

基于MAC,只能收发邮件,其它都拒绝
iptables -I Filter -m mac --mac-source 00:0A:EB:97:79:A1 -j DROP
iptables -I Filter -m mac --mac-source 00:0A:EB:97:79:A1 -p tcp --dport 25 -j ACCEPT
iptables -I Filter -m mac --mac-source 00:0A:EB:97:79:A1 -p tcp --dport 110 -j ACCEPT

禁用MSN配置
iptables -A Filter -p udp --dport 9 -j DROP
iptables -A Filter -p tcp --dport 1863 -j DROP
iptables -A Filter -p tcp --dport 80 -d 207.68.178.238 -j DROP
iptables -A Filter -p tcp --dport 80 -d 207.46.110.0/24 -j DROP

只允许PING 202。96。134。133 其它公网IP都不许PING
iptables -A Filter -p icmp -s 192.168.1.22 -d 202.96.134.133 -j ACCEPT
iptables -A Filter -p icmp -j DROP

禁止某个MAC地址访问internet:
iptables -I Filter -m mac --mac-source 00:20:18:8F:72:F8 -j DROP

禁止某个IP地址的PING:
iptables –A Filter –p icmp –s 192.168.0.1 –j DROP

禁止某个IP地址服务:
iptables –A Filter -p tcp -s 192.168.0.1 --dport 80 -j DROP
iptables –A Filter -p udp -s 192.168.0.1 --dport 53 -j DROP

只允许某些服务,其他都拒绝(2条规则)
iptables -A Filter -p tcp -s 192.168.0.1 --dport 1000 -j ACCEPT
iptables -A Filter -j DROP

禁止某个IP地址的某个端口服务
iptables -A Filter -p tcp -s 10.10.10.253 --dport 80 -j ACCEPT
iptables -A Filter -p tcp -s 10.10.10.253 --dport 80 -j DROP

禁止某个MAC地址的某个端口服务

iptables -I Filter -p tcp -m mac --mac-source 00:20:18:8F:72:F8 --dport 80 -j DROP

禁止某个MAC地址访问internet:
iptables -I Filter -m mac --mac-source 00:11:22:33:44:55 -j DROP

禁止某个IP地址的PING:
iptables –A Filter –p icmp –s 192.168.0.1 –j DROP

移动网络NAT心跳过期时间

心跳典型值

WhatsApp Line GCM
WIFI 4分45秒 3分20秒 15分钟
手机网络 4分45秒 7分钟 28分钟

移动NAT时间

大部分移动无线网络运营商都在链路一段时间没有数据通讯时,会淘汰 NAT表中的对应项,造成链路中断。下表列出一些已测试过的网络的NAT超时时间(更多数据由于测试条件所限没有测到):

地区/网络 NAT超时时间
中国移动3G和2G 5分钟
中国联通2G 5分钟
中国电信3G 大于28分钟
美国3G 大于28分钟
台湾3G 大于28分钟

长连接心跳间隔必须要小于NAT超时时间(aging-time),如果超过aging-time不做心跳,TCP长连接链路就会中断。

 

心跳的实现一例:


a. 连接后主动到服务器Sync拉取一次数据,确保连接过程的新消息。
b. 心跳周期的Alarm 唤醒后,一般有几秒的cpu 时间,无需wakelock。
c. 心跳后的Alarm防止发送超时,如服务器正常回包,该Alarm 取消。
d. 如果服务器回包,系统通过网络唤醒,无需wakelock。

 

 

中国国际互联网的接口

海底光缆是国际互联网的骨架。光缆的多少,代表一国与互联网的联系是否紧密。
有人利用微软的Bing地图,以及wikipedia的数据,做出了一幅互动式的世界海底光缆分布图。
中国大陆的海底光缆连接点只有三个,因此非常容易对出入境的信息进行控制。
第一个是青岛(2条光缆)。
第二个是上海(6条光缆)。
第三个是汕头(3条光缆)。
由于光缆之间存在重合,所以实际上,中国大陆与Internet的所有通道,就是3个入口6条光缆。
1. APCN2(亚太二号)海底光缆
带宽:2.56Tbps
长度:19000km
经过地区:中国大陆、香港、台湾、日本、韩国、马来西亚、菲律宾。
入境地点:汕头,上海。

2. CUCN(中美)海底光缆
带宽:2.2Tbps
长度:30000km
经过地区:中国大陆,台湾,日本,韩国,美国。
入境地点:汕头,上海。

3. SEA-ME-WE 3(亚欧)海底光缆
带宽:960Gbps
长度:39000km
经过地区:东亚,东南亚,中东,西欧。
入境地点:汕头,上海。

4. EAC-C2C海底光缆
带宽:10.24Tbps
长度:36800km
经过地区:亚太地区
入境地点:上海,青岛

5. FLAG海底光缆
带宽:10Gbps
长度:27000km
经过地区:西欧,中东,南亚,东亚
入境地点:上海

6. Trans-Pacific Express(TPE,泛太平洋)海底光缆
带宽:5.12Tbps
长度:17700km
经过地区:中国大陆,台湾,韩国,美国
入境地点:上海,青岛

摘自:http://blog.sina.com.cn/s/blog_604a480b0102vi13.html

some license

BSD-3 + 专利

Apache 2.0 许可

MIT 许可

GPL 许可

  • MongoDB Inc.=> MongoDB (license, GNU AGPL v3).
  • JPMorgan => Quorum (license, GNU LGPL v3).
  • VMware => Photon (license, GNU LGPL v2.1).

MPL 2.0 许可

BSD-3 许可

  • Google => Golang (license, with weak patent retaliation), LevelDB (license, no patent retaliation).
  • Yahoo => Pure.css (license).
  • Sentry => Sentry (license).
  • Flipboard => react-canvas (license), FLEX (license).
摘自网络和一张图:

转自:https://www.oschina.net/news/88307/75-popular-projects-open-source-licenses

选择图:

占比图:
2019年

主要的协议的权利和义务:

OpenSSL 生成自签名证书(简)

OpenSSL 是 SSL 和 TLS 协议的开放式源代码实现。它在标准通信层上提供了加密传输层,允许其与诸多网络应用程序和服务相结合。Cloud Management Console 中的缺省 SSL 概要文件具有通用公共名称。将 SSL 概要文件关联至网关集群时,如果使用缺省 SSL 概要文件,那么发出 API 调用的应用程序可能无法根据提供的证书验证其所连接到的主机名。在这种情况下,您可以生成一个新的自签名证书, 以表示应用程序可以验证的公共名称。该主题告诉您如何使用 OpenSSL 工具箱生成自签名 SSL 证书,以启用 HTTPS 连接。

过程

要使用 OpenSSL 生成自签名 SSL 证书,请完成以下步骤:

  1. 写下您的 SSL 证书的公共名称 (CN)。 该公共名称 (CN) 是使用该证书的系统的标准名称。 如果您使用的是动态 DNS,那么 CN 应该具有通配符,例如: *.api.com. 否则,使用网关集群中设置的主机名或 IP 地址(例如,192.16.183.131dp1.acme.com)。
  2. 运行以下 OpenSSL 命令来生成您的专用密钥和公用证书。回答问题并在出现提示时输入公共名称。
    openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out certificate.pem
  3. 检查已创建的证书:
    openssl x509 -text -noout -in certificate.pem
  4. 将密钥和证书组合在 PKCS#12 (P12) 捆绑软件中:
     openssl pkcs12 -inkey key.pem -in certificate.pem -export -out certificate.p12
  5. 验证您的 P12 文件。
    openssl pkcs12 -in certificate.p12 -noout -info
  6. 文章来源:

https://www.ibm.com/support/knowledgecenter/zh/SSWHYP_4.0.0/com.ibm.apimgmt.cmc.doc/task_apionprem_gernerate_self_signed_openSSL.html