In-Memory SQL / NoSQL - сохраняйте возможность запроса - возможно, используйте MySQL или SQL Server - PullRequest
0 голосов
/ 09 февраля 2012

Я бы хотел иметь возможность запускать набор записей / документов в хранилище данных, но всегда сохранять эти записи в оперативной памяти.Мне нужно всего лишь около 1,5 ГБ до 2 ГБ оперативной памяти (потенциально меньше).Это было бы на основе сервера, а не встроенного.

Я знаю, что хранилища ключей в памяти не будут работать для меня, потому что мне нужна расширенная возможность запросов.

Я знаю, что MySQL может делать на основе памятитаблицы, но не уверен, что люди используют эту функцию для того, о чем я думаю.Может ли SQL Server закреплять таблицы в памяти?Вся таблица?

Какие еще хранилища данных мне нужно посмотреть?Запросы Map / Reduce style также подойдут, если быстро.

Ответы [ 4 ]

1 голос
/ 09 февраля 2012

Если вы можете представить свои данные в виде коллекции объектов, то вы можете просто использовать Linq в качестве функции «расширенного запроса» и делать все это в памяти: это будет НАМНОГО быстрее, чем почти все из базы данных решений там. Если вы можете хранить все свои данные в памяти, то даже не беспокойтесь о базе данных.

Примечание: если вы делаете это в .NET, вам придется строить свой проект в 64-битном режиме, потому что вы не можете иметь коллекцию, которая имеет более ~ 1,5 ГБ данных в оперативной памяти на 32- Битовое приложение. Если вы не можете собрать / запустить в 64-битном режиме, то вам может потребоваться база данных.

Обновление

Я не уверен, что следую тому, что вы говорите: я не совсем уверен, что такое распространенная система, и это заставило бы меня поверить, что я не использую распространенную систему. Я также не знаю, что такое «доморощенный» объект или что такое «доморощенная» система .NET. Я использую только стандарт .NET 4.0, и когда я говорю объекты, я специально имел в виду, что вы пишете классы, которые могут хранить ваши данные. После этого вы загружаете свои данные в память (я не знаю, как вы получаете эти данные: файл, базу данных, сеть и т. Д.), А затем Linq выполняет ORM для вас. Безопасность потоков имеет значение только тогда, когда вы обращаетесь к своей внутренней коллекции объектов, и вы можете сделать это с помощью простой блокировки.

О, а если это доморощенная система .NET - размещаются ли эти объекты на сервере и получают ли они поражение от нескольких клиентов?

Для данных, с которыми я имею дело, мне не нужны никакие расширенные возможности запросов (ни в памяти, ни для получения их из базы данных), поэтому мы храним все, что не вписывается в память встроенная база данных ( LevelDB ). Таким образом, все наши данные хранятся на диске, и, когда нам это нужно, мы выбираем самый короткий / быстрый маршрут, чтобы поместить их в память. Переход по сети только замедлит вас, так что вы можете сделать это, но делать это только тогда, когда это абсолютно необходимо (т. Е. У вас жесткое ограничение на то, что ваши данные объемом 2 ГБ находятся в базе данных где-то, кроме вашей локальной машины).

1 голос
/ 10 февраля 2012

VoltDB - это совместимая с ACID база данных SQL, которая оптимизирована для высокоскоростной OLTP. Он работает на 64-битной Linux или Mac OS X, имеет версию сообщества с открытым исходным кодом и клиентские библиотеки на нескольких языках.

Когда вы говорите «расширенные возможности запросов», это звучит так, как будто это скорее случай использования OLAP, но если запросы имеют базовую сложность, это может хорошо подойти для VoltDB. Не могли бы вы рассказать больше о вашем случае использования?

1 голос
/ 09 февраля 2012

SQLLite может работать в памяти для решения реляционной базы данных.Для нереляционной базы данных RavenDB может работать в памяти.

0 голосов
/ 10 февраля 2012

Я должен согласиться с Лириком здесь.В терминах .Net использование объектов для ваших данных и LINQ для запроса их коллекции должно быть одним из самых быстрых способов сделать то, о чем вы просите, но при этом иметь в своем распоряжении богатый язык запросов.

ЕслиВас беспокоит размер коллекции, и если вы сможете хранить всю информацию в памяти, вы можете обратиться к таким проектам, как Memcached , чтобы помочь вам.

ОБНОВЛЕНИЕ

Я построил пример использования Linq с объектом критерия для запроса списка продуктов (хотя это может легко быть база данных Linq to Sql)

Сначалапример класса продукта:

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; }

    }
}

Теперь пример класса Критерии продукта

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()
        {

        }
    }
}

Пример репозитория - с использованием списков

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();
        }
    }
}

Обратите внимание в методе FilterProducts, чтосписок фильтров зацикливается на каждом, проверяется, является ли он действительным фильтром с учетом текущего объекта критериев, а затем применяется при необходимости.

Вот интерфейс 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());
        }
    }
}

Обратите внимание, что вам понадобится класс 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);
        }
    }
}

Наконец, вотнебольшое консольное приложение, показывающее идею в действии:

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();

        }
    }
}

Вы можете расширить эту идею, чтобы добавить несколько фильтров и даже работать, если функция, возвращаемая из IProductFilter, должна быть И или ИЛИ для выражения,

Фильтры могут быть введены в хранилище, что позволяет легко их менять во время выполнения.

Надеюсь, это даст вам некоторые идеи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...