可以在SQL中的数据库中完成二进制搜索吗?

时间:2009-11-24 01:42:07

标签: c# database search datareader

行。我使用C#编程语言访问一个简单的数据库(在Microsoft SQL Server上)

目前,我正在使用DataReader对象来访问数据库。 所以这是我的问题:是否可以对特定数据进行二进制搜索(在C#中),以便我可以更快地进行搜索?

目前,我正在使用简单的while循环来搜索数据库的内容。我相信这是按顺序完成的。

while (pReader.Read())
{
   if ((String)pReader["theData"] == "The_thing_im_searching_for")
   break;
}

那么有没有办法进行二元搜索?

6 个答案:

答案 0 :(得分:19)

如果您正在使用数据库,则应编写一个select语句来搜索您要查找的内容,而不是手动迭代数据库。没有理由重新发明轮子。

答案 1 :(得分:6)

正如Donnie指出的那样,如果您在SQL中表达谓词,数据库将选择自动提取数据的最有效方式。

试试这个:

string sql = "SELECT * FROM Foo WHERE theData = 'The_thing_im_searching_for'"
SqlDataAdapter adapter = new SqlDataAdapter(sql);
DataTable table = new DataTable();
adapter.Fill(table);

foreach(DataRow row in table.Rows) {
    // Do whatever you want here
}

答案 2 :(得分:2)

本着Donnies的回答,我提供了一个简单的SQL示例,说明如何使用比动态构造的SQL更安全的机制来检索你所使用的(正如其他人建议的那样)

在简单的情况下,您应该为数据库中每个实体的应用程序可用的每个“创建”,“读取”,“更新”,“删除”操作创建存储过程。 (这在大型生产系统中并非100%正确,但它比在应用程序中构建的动态生成的SQL更好)

现在对于READ,如果没有提供参数,则列出所有参数。这是我工作中的数据库架构师讲授的方法的简化版本 - 这里我们不将检索存储过程与列表过程分开,它们实际上是相同的操作。从长远来看,这将支付更少的SQL代码。

CREATE PROCEDURE usp_ReadName 
 @name_id bigint=NULL
AS
BEGIN
 SET NOCOUNT ON;
 if (@name_id IS NULL)
  SELECT name_id,name,description 
            from name with(nolock)
 else
  select name_id,name,description 
            from name with(nolock) 
            where name_id = @name_id  
END
GO

现在是C#方面。 为了保存结果,我们定义了一个数据传输实体。一般来说,它们比数据表更轻,重量更快,使用效率更高。如果速度,大量数据或有限的内存不是一个问题,只需使用数据表。 (平均而言,你可以节省大约40%+内存,大约10%的速度 - 结构的100K记录高峰值内存使用140MB带有数据表,而DTE峰值高达78MB)

/// <summary>
/// A simple data transfer entity
/// </summary>
public struct name_data
{
    public long name_id;
    public string name;
    public string description;
    public name_data(long id, string n, string d)
    {
        name_id = id;
        name = n;
        description = d;
    }
}

现在我们使用nullable参数语法在C#中捕获结果。此代码假定您已经打开了sql连接

conn.Open();
using (SqlCommand cmd = new SqlCommand("usp_ReadName",conn))
{
    cmd.CommandType = CommandType.StoredProcedure;
    if (id.HasValue)
        cmd.Parameters.Add("@name_id", SqlDbType.BigInt).Value = id.Value;
    using (SqlDataReader reader = cmd.ExecuteReader())
    {

        if (reader.HasRows)
        {
            while (reader.Read())
            {
                dte.name_data item = new dte.name_data(
                    (long)reader["name_id"],
                    reader["name"].ToString(),
                    reader["description"].ToString());
                items.Add(item);
            }
        }
    }
}

答案 3 :(得分:0)

Daniel和Donnie在这里的回答告诉你这是一个坏主意是非常正确的。

然而,对您的问题更直接的回答是,您可以搜索二进制数据,但我不确定这是您正在寻找的。

MSSQL可以以varbinary格式存储数据,您可以对此varbinary数据进行搜索。事实上,您可以在这篇文章中找到有关这样做的更多信息:Dealing with a varbinary field in VB.NET

以下是执行此操作的查询示例。

byteArrayToken = StringToByteArray(stringToken)
scSelectThing.CommandText = "select thing from table where token=@token"
Dim param As SqlParameter = scSelectThing.Parameters.Add("@token", SqlDbType.VarBinary)
param.Value = byteArrayToken
lbOutput2.Text = scSelectThing.ExecuteScalar()

答案 4 :(得分:0)

  

那么有没有办法做二进制文件   搜索?

SQL Server端直接SELECT的问题是DB将对表进行线性搜索,除非您正在使用的列上有索引;然后DB可以更聪明。

如果您仍然需要阅读整个表格(例如,您可以在短时间内再次搜索它),那么您可以考虑使用ArrayList.BinarySearch()。当然,要使其工作,数据将需要在ArrayList中按排序顺序。

答案 5 :(得分:0)

感谢所有的信息(周杰伦再次)。我相信我已经回答了我的问题。

问题是,我在数据库中有很多信息。搜索特定项目将花费大量时间。所以我有兴趣做二分搜索。

当我执行SELECT命令查找内容时,我不知道MSSQL(在后台)是否进行二分查找。但如果RickNZ(上图)说的是真的

  

直接选择SELECT的问题   SQL Server端是DB   将通过线性搜索   表除非您正在使用的列   有一个索引;然后是DB   可以更聪明。

如果我有“索引”信息,那么数据库将最有效地进行搜索(二进制搜索)。