亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > SQL Server > 正文

SQL2005CLR函數擴展 - 關于山寨索引

2024-08-31 01:01:03
字體:
來源:轉載
供稿:網友
本文只是一個山寨試驗品,思路僅供參考.
--------------------------------------------------------------------------------
原理介紹:
索引建立
目錄結構劃分方案也只是很簡易的實現了一下,通過unicode把任意連續的兩個字符(中文或英文)分為4個字節來做四層目錄,把索引的內容對應的主關鍵字(主要為了使用sql索引和唯一性)作為文件名,兩個字符在索引內容中的位置作為文件后綴來存儲.文件本身為0字節,不保存任何信息.

比如一條數據 "pk001","山寨索引"
山寨索引 四個字的unicode為
[0]: 113
[1]: 92
[2]: 232
[3]: 91
[4]: 34
[5]: 125
[6]: 21
[7]: 95
那么對應的文件結構為
../113/92/232/91/pk001 .0
../232/91/34/125/pk001 .1
../34/125/21/95/pk001 .2

索引使用
比如搜索"寨索引 "
則搜索 "../232/91/34/125/" 目錄下的所有文件,然后根據 pk001 .1的文件后綴名1,去看 ../34/125/21/95/pk001.2文件是否存在.依次類推,最后返回一個結果集.
--------------------------------------------------------------------------------
實用性
具體的實用性還有待驗證.這只是實現了精確的like搜索,而不能做常見搜索引擎的分詞效果.另外海量數據重建索引的性能也是面臨很嚴峻的問題,比如cpu負載和磁盤io負載.關于windows一個目錄下可以保持多少個文件而不會對文件搜索造成大的性能損失也有待評估,不過這個可以考慮根據主鍵的文件名hash來增加文件目錄深度降低單一目錄下的文件數量.
--------------------------------------------------------------------------------
演示效果
實現了針對test標的name和caption兩個字段作索引搜索.
 
-- 設置和獲取索引文件根目錄
--select dbo.xfn_SetMyIndexFileRoot('d:/MyIndex')
--select dbo.xfn_GetMyIndexFileRoot()
-- 建立測試環境
 go
create table test( id uniqueidentifier , name nvarchar ( 100), caption nvarchar ( 100))
insert into test select top 3 newid (), ' 我的索引 ' , ' 測試 ' from sysobjects
insert into test select top 3 newid (), ' 我的測試 ' , ' 索引 ' from sysobjects
insert into test select top 3 newid (), ' 測試索引 ' , ' 測試索引 ' from sysobjects
insert into test select top 3 newid (), ' 我的索引 ' , ' 索引 ' from sysobjects
create index i_testid on test( id)
-- 建立索引文件
declare @t int
select @t=
dbo. xfn_SetKeyForMyIndex( id, 'testIndex' , name + ' ' + caption)   
from test
-- 查詢數據
select  a.*   from   test a, dbo. xfn_GetKeyFromMyIndex( '測試 索引 我的' , 'testIndex' )  b
    where a. id= b. pk
/*
0C4634EA-DF94-419A-A8E5-793BD5F54EED   我的索引 測試
2DD87B38-CD3F-4F14-BB4A-00678463898F   我的索引 測試
8C67A6C3-753F-474C-97BA-CE85A2455E3E   我的索引 測試
C9706BF1-FB1F-42FB-8A48-69EC37EAD3E5   我的測試 索引
8BBF25CC-9DBB-4FCB-B2EB-D318E587DD5F   我的測試 索引
8B45322D-8E46-4691-961A-CD0078F1FA0A   我的測試 索引
*/
--drop table test
--------------------------------------------------------------------------------
clr代碼如下:編譯為MyFullIndex.dll

復制代碼 代碼如下:


using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Collections.Generic;
public partial class UserDefinedFunctions
{
    /// <summary>
    /// 設置索引目錄
    /// </summary>
    /// <param></param>
    /// <returns></returns>
    [Microsoft.SqlServer.Server.SqlFunction ]
    public static SqlBoolean SetRoot(SqlString value)
    {
        if (value.IsNull) return false ;
        if (System.IO.Directory .Exists(value.Value))
        {
            root = value.Value;
            return true ;
        }
        else
        {
            return false ;
        }
    }
    /// <summary>
    /// 獲取索引目錄
    /// </summary>
    /// <returns></returns>
    [Microsoft.SqlServer.Server.SqlFunction ]
    public static SqlString GetRoot()
    {
        return new SqlString (root);
    }
    /// <summary>
    /// 建立索引
    /// </summary>
    /// <param> 主鍵 </param>
    /// <param> 索引名稱 </param>
    /// <param> 索引內容 </param>
    /// <returns></returns>
    [Microsoft.SqlServer.Server.SqlFunction ]
    public static SqlInt32 SetIndex(SqlString key,SqlString indexName,SqlString content)
    {
        if (key.IsNull || content.IsNull||indexName.IsNull) return 0;
        return _setIndex(key.Value,indexName.Value, content.Value);
    }

    /// <summary>
    /// 查詢索引
    /// </summary>
    /// <param> 關鍵字(空格區分) </param>
    /// <param> 索引名稱 </param>
    /// <returns></returns>
    [SqlFunction (TableDefinition = "pk nvarchar(900)" , Name = "GetIndex" , FillRowMethodName = "FillRow" )]
    public static IEnumerable GetIndex(SqlString word,SqlString indexName)
    {

        System.Collections.Generic.List <string > ret = new List <string >();
        if (word.IsNull || indexName.IsNull) return ret;
        return _getIndex2(word.Value, indexName.Value);
    }

    public static void FillRow(Object obj, out SqlString pk)
    {
        string key = obj.ToString();
        pk = key;
    }
    static string root = @"d:/index" ;

    /// <summary>
    /// 獲取有空格分隔的索引信息
    /// </summary>
    /// <param></param>
    /// <param></param>
    /// <returns></returns>
    static System.Collections.Generic.List <string > _getIndex2(string word, string indexName)
    {
        string [] arrWord = word.Split(new char [] { ' ' }, StringSplitOptions .RemoveEmptyEntries);

        System.Collections.Generic.List <string > key_0 = _getIndex(arrWord[0], indexName);

        if (arrWord.Length == 0) return key_0;
        System.Collections.Generic.List <string > [] key_list=new List <string >[arrWord.Length-1];
        for (int i = 0; i < arrWord.Length-1; i++)
        {
            System.Collections.Generic.List <string > key_i = _getIndex(arrWord[i+1],indexName);
            key_list[i] = key_i;
        }

        for (int i=key_0.Count-1;i>=0;i--)
        {
            foreach (System.Collections.Generic.List <string > key_i in key_list)
            {
                if (key_i.Contains(key_0[i]) == false )
                {
                    key_0.RemoveAt(i);
                    continue ;
                }
            }
        }
        return key_0;
    }
    /// <summary>
    /// 獲取單個詞的索引信息
    /// </summary>
    /// <param></param>
    /// <param></param>
    /// <returns></returns>
    static System.Collections.Generic.List <string > _getIndex(string word, string indexName)
    {
        System.Collections.Generic.List <string > ret = new List <string >();
        byte [] bWord = System.Text.Encoding .Unicode.GetBytes(word);
        if (bWord.Length < 4) return ret;

        string path = string .Format(@"{0}/{1}/{2}/{3}/{4}/{5}/" , root,indexName, bWord[0], bWord[1], bWord[2], bWord[3]);
        if (System.IO.Directory .Exists(path) == false )
        {
            return ret;
        }
        string [] arrFiles = System.IO.Directory .GetFiles(path);

        foreach (string file in arrFiles)
        {
            string key = System.IO.Path .GetFileNameWithoutExtension(file);
            string index = System.IO.Path .GetExtension(file).TrimStart(new char [] { '.' });
            int cIndex = int .Parse(index);
            bool bHas = true ;
            for (int i = 2; i < bWord.Length - 3; i = i + 2)
            {
                string nextFile = string .Format(@"{0}/{1}/{2}/{3}/{4}/{5}/{6}.{7}" ,
                    root, indexName, bWord[i + 0], bWord[i + 1], bWord[i + 2], bWord[i + 3], key, ++cIndex);

                if (System.IO.File .Exists(nextFile) == false )
                {
                    bHas = false ;
                    break ;
                }
            }
            if (bHas == true &&ret.Contains(key)==false )
                ret.Add(key);

        }
        return ret;
    }

    /// <summary>
    /// 建立索引文件
    /// </summary>
    /// <param></param>
    /// <param></param>
    /// <param></param>
    /// <returns></returns>
    static int _setIndex(string key,string indexName, string content)
    {
        byte [] bContent = System.Text.Encoding .Unicode.GetBytes(content);
        if (bContent.Length <= 4) return 0;
        for (int i = 0; i < bContent.Length - 3; i = i + 2)
        {
            string path = string .Format(@"{0}/{1}/{2}/{3}/{4}/{5}/" , root,indexName, bContent[i + 0], bContent[i + 1], bContent[i + 2], bContent[i + 3]);
            if (System.IO.Directory .Exists(path) == false )
            {
                System.IO.Directory .CreateDirectory(path);
            }
            string file = string .Format(@"{0}/{1}.{2}" , path, key, i / 2);

            if (System.IO.File .Exists(file) == false )
            {
                System.IO.File .Create(file).Close();
            }
        }
        return content.Length;
    }
};


--------------------------------------------------------------------------------
部署的sql腳本如下
--drop function dbo.xfn_SetMyIndexFileRoot
--drop function dbo.xfn_GetMyIndexFileRoot
--drop function dbo.xfn_GetKeyFromMyIndex
--drop function dbo.xfn_SetKeyForMyIndex
--drop assembly MyFullIndex
--go
CREATE ASSEMBLY MyFullIndex FROM 'd:/SQLCLR/MyFullIndex.dll' WITH PERMISSION_SET = UnSAFE;
--
go
-- 索引搜索
CREATE FUNCTION dbo. xfn_GetKeyFromMyIndex ( @word nvarchar ( max ), @indexName  nvarchar ( 900))   
RETURNS table ( pk nvarchar ( 100))
AS EXTERNAL NAME MyFullIndex. UserDefinedFunctions. GetIndex
go
-- 索引建立
CREATE FUNCTION dbo. xfn_SetKeyForMyIndex ( @pk nvarchar ( 900), @indexName  nvarchar ( 900), @word nvarchar ( max ))   
RETURNS int
AS EXTERNAL NAME MyFullIndex. UserDefinedFunctions. SetIndex
go
-- 獲取索引文件根目錄
CREATE FUNCTION dbo. xfn_GetMyIndexFileRoot ()   
RETURNS nvarchar ( max )
AS EXTERNAL NAME MyFullIndex. UserDefinedFunctions. GetRoot
go
-- 設置索引文件根目錄(默認目錄為 d:/myindex )
CREATE FUNCTION dbo. xfn_SetMyIndexFileRoot ( @FileRoot nvarchar ( max ))   
RETURNS bit
AS EXTERNAL NAME MyFullIndex. UserDefinedFunctions. SetRoot
go
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品成人久久av| 人人爽久久涩噜噜噜网站| 欧美裸体男粗大视频在线观看| 久久久久久尹人网香蕉| 精品女同一区二区三区在线播放| 日韩欧美中文字幕在线播放| 性色av一区二区三区红粉影视| 4438全国亚洲精品在线观看视频| 欧美视频在线观看 亚洲欧| 久久亚洲私人国产精品va| 欧美激情中文字幕乱码免费| 国产国语刺激对白av不卡| 亚洲欧美日韩天堂| 久久99热精品这里久久精品| 成人黄色av免费在线观看| 中文字幕av一区二区| 亚洲精品免费一区二区三区| 欧美性视频在线| 中文字幕精品视频| 国产欧美一区二区三区久久| 91在线无精精品一区二区| 国产成人精品视频| 欧美高清电影在线看| 精品视频久久久| 色妞在线综合亚洲欧美| 成人黄色免费在线观看| 欧美性猛交xxxx乱大交蜜桃| 国产精品av网站| 国产精品久在线观看| 欧美综合一区第一页| 色樱桃影院亚洲精品影院| 久久久亚洲国产天美传媒修理工| 2019中文字幕在线| 欧美激情亚洲激情| 欧美黄色小视频| 韩国精品久久久999| 国产精品久久精品| 成人国产精品色哟哟| 91超碰中文字幕久久精品| 亚洲欧洲一区二区三区久久| 精品国偷自产在线| 欧美日韩激情小视频| 国产亚洲精品va在线观看| 日韩第一页在线| 亚洲国产欧美一区| 欧美成人午夜激情视频| 不卡av电影在线观看| 亚洲久久久久久久久久久| 欧美日韩亚洲天堂| 久久久www成人免费精品张筱雨| 国产手机视频精品| 91免费观看网站| 欧美性高潮在线| 97色伦亚洲国产| 欧美在线视频a| 国产99在线|中文| 国内精品久久久久久影视8| 中文字幕自拍vr一区二区三区| 欧美日韩亚洲一区二区| 亚洲激情国产精品| 欧美激情视频在线免费观看 欧美视频免费一| 欧美性猛交丰臀xxxxx网站| 欧美大尺度在线观看| 97视频在线免费观看| 日韩国产精品亚洲а∨天堂免| 色yeye香蕉凹凸一区二区av| 精品久久久国产| 色噜噜狠狠色综合网图区| 狠狠躁夜夜躁人人躁婷婷91| 亚洲美女中文字幕| 国模精品视频一区二区| 日韩激情视频在线| 亚洲国产精品成人精品| 亚洲国产欧美在线成人app| 中文字幕成人精品久久不卡| 亚洲福利在线播放| 91tv亚洲精品香蕉国产一区7ujn| 午夜美女久久久久爽久久| 国产成人精品免高潮费视频| 欧美日韩在线看| 欧美激情精品久久久久| 91av视频在线| 欧美在线视频一区| 亚洲人a成www在线影院| 日韩成人av在线播放| 国产精品精品视频一区二区三区| 国产中文欧美精品| 欧美激情网站在线观看| 色999日韩欧美国产| 久久久久国产精品一区| 欧美精品在线看| 国语自产在线不卡| 国产不卡在线观看| 最近中文字幕日韩精品| 久久综合伊人77777蜜臀| 精品国产欧美一区二区三区成人| 国产精品久久久久久婷婷天堂| 精品国产1区2区| 亚洲成人久久久| 91理论片午午论夜理片久久| 精品无人区乱码1区2区3区在线| 亚洲美女黄色片| 美日韩精品免费视频| 81精品国产乱码久久久久久| 久久影院中文字幕| 欧美性猛xxx| 91黑丝在线观看| 日韩欧美一区二区三区| 成人国产精品一区| 欧美成人激情在线| 日韩a**站在线观看| 日韩精品欧美国产精品忘忧草| 九九热视频这里只有精品| 欧美一级淫片videoshd| 97超视频免费观看| 97精品一区二区三区| 97视频在线观看网址| 国产精品日韩欧美综合| 欧美乱人伦中文字幕在线| 性欧美xxxx视频在线观看| 伊人久久男人天堂| 另类少妇人与禽zozz0性伦| 欧美色图在线视频| 97免费中文视频在线观看| 欧美性生活大片免费观看网址| 精品亚洲va在线va天堂资源站| 日韩欧美亚洲一二三区| 国产成人在线播放| 成人网欧美在线视频| 国产在线精品一区免费香蕉| 97色在线播放视频| 国产精品一区二区三区久久久| 国产一区二区三区视频| 日韩美女免费观看| 久久久噜久噜久久综合| 国产成人av在线播放| 国产香蕉精品视频一区二区三区| 亚洲一区二区三区在线视频| 日韩欧美在线字幕| 久久久精品在线观看| 日本sm极度另类视频| 精品一区电影国产| 九九热最新视频//这里只有精品| 欧洲s码亚洲m码精品一区| 国产成人精品亚洲精品| xxxx欧美18另类的高清| 国产精品美女999| 一区二区三区视频免费| 中文字幕欧美专区| 色无极影院亚洲| 亚洲精品免费一区二区三区| 亚洲精品国产精品国产自| 中文字幕亚洲欧美一区二区三区| 亚洲少妇中文在线| 国产精品久久久久久久久久久不卡| 国产精品毛片a∨一区二区三区|国| 日韩av网址在线| 国产视频精品久久久| 色噜噜国产精品视频一区二区| 国产一区二区三区在线播放免费观看| 久久国产精品久久久| 欧美成人精品激情在线观看| 欧美成人免费在线观看| 欧美猛男性生活免费|