简体   繁体   English

内存中SQL / NoSQL-保持查询能力-可能使用MySQL或SQL Server

[英]In-Memory SQL/NoSQL - Keep the ability to query - Maybe use MySQL or SQL Server

I'd I like to be able to run a set of records/documents in a data store but have those records fresh in RAM at all times. 我希望能够在数据存储中运行一组记录/文档,但始终将这些记录保存在RAM中。 I only need to use about 1.5GB to 2GB of RAM (potentially less). 我只需要使用大约1.5GB到2GB的RAM(可能更少)。 This would be server-based not embedded. 这将是基于服务器的而不是嵌入式的。

I know in-memory key-value stores will not work for me, because I need rich query capability. 我知道内存中的键值存储对我不起作用,因为我需要丰富的查询功能。

I know MySQL can do memory based tables, but not sure if people use this feature for what I'm thinking about. 我知道MySQL可以做基于内存的表,但是不能确定人们是否出于我的想法使用了此功能。 Can SQL Server pin tables in memory? SQL Server可以将表固定在内存中吗? The entire table? 整张桌子?

What other data stores should I be looking at? 我还应该查看哪些其他数据存储? Map/Reduce style querying would also be fine if fast. 如果速度很快,则Map / Reduce样式查询也可以。

SQLLite can run in memory for a relational database solution. SQLLite可以在内存中运行以获得关系数据库解决方案。 For a non-relational database, RavenDB can run in memory. 对于非关系数据库,RavenDB可以在内存中运行。

If you can represent your data as a collection of objects, then you can just use Linq as your "rich query" capability and do it all in memory: this will be MUCH faster than pretty much all of the database solutions out there. 如果您可以将数据表示为对象的集合,则可以仅使用Linq作为“丰富查询”功能,并在内存中完成所有操作:这将比其中的几乎所有数据库解决方案快得多。 If you can keep all of your data in memory, then don't even bother with a database. 如果您可以将所有数据保留在内存中,那么甚至不用理会数据库。

Note: if you're doing this in .NET, then you'll have to build your project in 64-bit mode because you cannot have a collection that has more than ~1.5 GB of data in RAM on a 32-bit application. 注意:如果您是在.NET中执行此操作,则必须在64位模式下构建项目,因为在32位应用程序中,RAM中的数据集不能超过1.5 GB。 If you can't build/run in 64-bit mode, then you might need a database. 如果您无法在64位模式下构建/运行,则可能需要一个数据库。

Update 更新资料

I'm not sure I'm following what you're saying: I'm not really sure what a prevalent system is and that would lead me to believe that I'm not using a prevalent system. 我不确定我是否遵循您的意思:我真的不确定什么是流行的系统,这会使我相信我没有使用流行的系统。 I also don't know what a "homegrown" object is or what is a "homegrown" .NET system. 我也不知道什么是“自产”对象或什么是“自产” .NET系统。 I'm using just the standard .NET 4.0 and when I say objects, I specifically meant that you write classes which can hold your data. 我只使用标准的.NET 4.0,当我说对象时,我的意思是说您编写可以保存数据的类。 From there on, you load your data in memory (I don't know how you get your data: file, database, network, etc) then Linq does the ORM for you. 从那里开始,您将数据加载到内存中(我不知道如何获取数据:文件,数据库,网络等),然后Linq为您执行ORM。 Thread safety only matters when you're accessing your internal collection of objects and you can do that with a simple lock. 线程安全仅在访问对象的内部集合时才重要,并且可以使用简单的锁来做到这一点。

Oh, and if it is homegrown .NET system - are these objects hosted on a server and getting hit by multiple clients? 哦,如果它是自产的.NET系统-这些对象是否托管在服务器上并受到多个客户端的攻击?

For the data I'm dealing with, I don't need any kind of rich query capability (neither in memory, nor to get it from a database), that's why we store anything we can't fit into memory into an embedded database ( LevelDB ). 对于我正在处理的数据,我不需要任何种类的丰富查询功能(既不在内存中,也不从数据库中获取),这就是为什么我们将内存中无法存储的任何内容存储到嵌入式数据库中的原因( LevelDB )。 This way, all of our data is contained on disk and when we need it, we take the shortest/fastest route to get it into memory. 这样,我们所有的数据都包含在磁盘上,并且在需要时,我们采用最短/最快的途径将其存入内存。 Going over a network will only slow you down, so you can do that, but only do it when you absolutely have to (ie you have a hard constraint that your 2GB data is on a database somewhere other than your local machine). 通过网络访问只会减慢您的速度,因此您可以这样做,但只有在绝对必须这样做时(即,您有严格的约束,即2GB数据位于本地计算机以外的其他数据库中),才可以这样做。

VoltDB is an in-memory ACID-compliant SQL database that is optimized for high velocity OLTP. VoltDB是一个内存中兼容ACID的SQL数据库,针对高速OLTP进行了优化。 It runs on 64-bit Linux or Mac OS X, has an open source community edition, and client libraries in several languages. 它运行在64位Linux或Mac OS X上,具有开放源代码社区版本,并具有多种语言的客户端库。

When you say "rich query capability" it sounds like it could be more of an OLAP use case, but if the queries are of basic complexity, it could be a good fit for VoltDB. 当您说“丰富的查询功能”时,听起来可能更像是OLAP用例,但是,如果查询具有基本的复杂性,则可能非常适合VoltDB。 Could you share more about your use case? 您能否分享有关用例的更多信息?

I have to agree with Lirik here. 我必须在这里同意Lirik。 In .Net terms using objects for your data and LINQ to query a collection of them has to be one of the fastest ways to do what you are asking for whilst still having a rich query language at your fingertips. 在.Net术语中,使用对象作为数据和LINQ来查询它们的集合必须是完成您所要查询的最快方法之一,同时仍然可以使用丰富的查询语言。

If you are worried about the size of the collection and if you will be able to hold all of the information in memory then you could have a look at projects such as Memcached to help you. 如果您担心集合的大小,并且能够将所有信息保存在内存中,那么可以看看Memcached之类的项目来为您提供帮助。

UPDATE 更新

I have built an example of using Linq with a criteria object to query a list of products (could easily be a Linq to Sql datatable though) 我建立了一个使用带有标准对象的Linq来查询产品列表的示例(尽管很容易成为Linq to Sql数据表)

First an example product class: 首先是示例产品类别:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Linq_Question
{
    public class Product
    {
        public enum Categories
        {
            CatOne,
            CatTwo,
            CatThree
        }

        public int Id { get; set; }
        public string Name { get; set; }
        public Categories Category { get; set; }
        public decimal Price { get; set; }

    }
}

Now an example Product Criteria class 现在是示例产品标准类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Linq_Question
{
    public class ProductCriteria
    {
        public Product.Categories? WhereCategoryIs { get; set; }
        public decimal? WherePriceIsGreaterThan { get; set; }
        public decimal? WherePriceIsLessThan { get; set; }
        public string WhereNameContains { get; set; }

        public ProductCriteria()
        {

        }
    }
}

An example repository - using lists 一个示例存储库-使用列表

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Linq_Question
{
    public class ProductRepository
    {
        private List<Product> products;

        public ProductRepository()
        {
            products = new List<Product>();
            products.Add(new Product() { Category = Product.Categories.CatOne, Id = 1, Name = "Product 1", Price = 100 });
            products.Add(new Product() { Category = Product.Categories.CatTwo, Id = 2, Name = "Product 2", Price = 120 });
            products.Add(new Product() { Category = Product.Categories.CatThree, Id = 3, Name = "Product 3", Price = 300 });
            products.Add(new Product() { Category = Product.Categories.CatOne, Id = 4, Name = "Product 4", Price = 400 });
            products.Add(new Product() { Category = Product.Categories.CatTwo, Id = 5, Name = "Product 5", Price = 500 });
            products.Add(new Product() { Category = Product.Categories.CatThree, Id = 6, Name = "Product 6", Price = 600 });
        }

        public IEnumerable<Product> Retrieve(ProductCriteria criteria)
        {
            return this.products.Where(FilterProducts(criteria));
        }

        private Func<Product, bool> FilterProducts(ProductCriteria criteria)
        {
            Expression<Func<Product, bool>> predicate = PredicateBuilder.True<Product>();
            List<IProductFilter> filters = new List<IProductFilter>();
            filters.Add(new PriceIsGreaterThanFilter());
            filters.Add(new CategoryFilter());

            foreach (var item in filters)
            {
                if (item.IsValidFilter(criteria))
                {
                    predicate = predicate.And(item.ApplyFilter(criteria));
                }
            }
            return predicate.Compile();
        }
    }
}

Notice in the FilterProducts method that a list of filters are looped over each one is checked to see if it is a valid filter given the current criteria object and then applied if required. 请注意,在FilterProducts方法中,检查了一个循环遍历每个过滤器的列表,以查看给定当前条件对象是否为有效过滤器,然后根据需要应用。

Here is the IProductFilter interface and some example filters 这是IProductFilter接口和一些示例过滤器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Linq_Question
{
    public interface IProductFilter
    {
        bool IsValidFilter(ProductCriteria criteria);
        Expression<Func<Product, bool>> ApplyFilter(ProductCriteria criteria);
    }

    public class CategoryFilter : IProductFilter
    {
        public bool IsValidFilter(ProductCriteria criteria)
        {
            return (criteria.WhereCategoryIs.HasValue);
        }

        public Expression<Func<Product, bool>> ApplyFilter(ProductCriteria criteria)
        {
            return (p => p.Category == criteria.WhereCategoryIs.GetValueOrDefault());
        }
    }

    public class PriceIsGreaterThanFilter : IProductFilter
    {
        public bool IsValidFilter(ProductCriteria criteria)
        {
            return (criteria.WherePriceIsGreaterThan.HasValue);
        }

        public Expression<Func<Product, bool>> ApplyFilter(ProductCriteria criteria)
        {
            return (p => p.Price > criteria.WherePriceIsGreaterThan.GetValueOrDefault());
        }
    }
}

Please note you will need the PredicateBuilder class - found http://www.albahari.com/nutshell/predicatebuilder.aspx 请注意,您将需要PredicateBuilder类-http: //www.albahari.com/nutshell/predicatebuilder.aspx

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;

namespace Linq_Question
{
    public static class PredicateBuilder
    {
        public static Expression<Func<T, bool>> True<T>() { return f => true; }
        public static Expression<Func<T, bool>> False<T>() { return f => false; }

        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr1,
                                                            Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
        }

        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr1,
                                                             Expression<Func<T, bool>> expr2)
        {
            var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
            return Expression.Lambda<Func<T, bool>>
                  (Expression.AndAlso(expr1.Body, invokedExpr), expr1.Parameters);
        }
    }
}

Finally, here is a small console app showing the idea in action: 最后,这是一个小型控制台应用程序,显示了实际的想法:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Linq_Question
{
    class Program
    {
        static void Main(string[] args)
        {
            ProductRepository repo = new ProductRepository();
            Console.WriteLine("Items over 100");
            foreach (var item in repo.Retrieve(new ProductCriteria() { WherePriceIsGreaterThan = 100 }))
            {
                Console.WriteLine(string.Format("Name {0}, Category {1}, Price {2}", item.Name, item.Category, item.Price));
            }
            Console.WriteLine("Items with a Category of Two");
            foreach (var item in repo.Retrieve(new ProductCriteria() { WhereCategoryIs = Product.Categories.CatTwo }))
            {
                Console.WriteLine(string.Format("Name {0}, Category {1}, Price {2}", item.Name, item.Category, item.Price));
            }

            Console.Read();

        }
    }
}

You could expand on this idea to add multiple filters and even work out if the function returned from the IProductFilter should be AND or OR'd to the expression. 您可以扩展这个想法以添加多个过滤器,甚至可以算出从IProductFilter返回的函数应该对表达式进行“与”还是“或”运算。

The filters could be injected in to the repository - making them easy to change at runtime. 可以将过滤器注入到存储库中-使它们在运行时易于更改。

I hope this gives you some ideas. 我希望这能给您一些想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM