Было бы неправильно использовать статический объект вместо базы данных?

Огромное спасибо Парфе за то, что он указал мне правильное направление, особенно с paste0s. Я действительно боролся с тем, что split (), кажется, переименовывает столбцы каждого DF в списке, который нарушает код (заставляет его возвращать NULL).

Это еще одно решение, которое более точно соответствует тому, что мне нужно, чтобы код выполнялся в дикой природе (т.е. не для небольшого набора данных, такого как lalonde). Надеюсь, это пригодится кому-то в будущем.

## packages
library(tidyverse)
library(MatchIt)

##data
data("lalonde")

## randomize the data because lalonde is sorted by treated so the mathcing will fail for some subsets
lalonde2 <- lalonde[sample(nrow(lalonde)),]

##set the size of each subset
n <- 30
nr <- nrow(lalonde2)

### make the subsets
splitter <- split(lalonde2, rep(1:ceiling(nr/n), each=n, length.out=nr))

## write them to file (with replaced names because split() changed them)
for(i in 1:length(splitter)){
  names(splitter[[i]]) <- c("treat", "age", "educ", "black", "hispan", "married", "nodegree", "re74", "re75", "re78")
  write.csv(splitter[[i]], file = paste0("data_", i, ".csv")) 
}

## remove the big one 
rm(splitter)

## for loop that runs through each of the saved files from earlier, runs a matching model and matches the data and writes it to a file all in one

require(stringr)
for (i in 1:ceiling(nr/n)){
  file<- read.csv(str_c("data_",i,".csv"))
  write.csv(match.data(matchit(treat ~ age + educ, method = "nearest", data = file, ratio = 1)), file = paste0("matched_data_", i, ".csv"))
  ### remove the data after each iteration
  rm(file)

}
5
задан Daniel Rikowski 3 May 2009 в 09:30
поделиться

11 ответов

Я бы по-прежнему использовал базу данных для резервного копирования, но на клиенте использовал бы кэшируемый API-интерфейс, такой как oscache, для хранения данных в локальной файловой системе для быстрого доступа, а затем, если система выходит из строя, восстановите кеш из базы данных и продолжить использование кеша в вашем коде

4
ответ дан 13 December 2019 в 05:42
поделиться

Обычно возвращается и кусается предположение, что что-то никогда не изменится. Поэтому, если вы позже получите требования, которые включают обновление значений, добавление новых и наличие доступа к данным нескольких клиентов, если вы уже используете базу данных, у вас будет меньше работы. Вместо этого сделайте некоторое кэширование на стороне клиента, чтобы получить повышение производительности. Просто мой 2с.

1
ответ дан 13 December 2019 в 05:42
поделиться

Проблемы, с которыми вы столкнетесь, если данные изменятся, и вам нужно будет каждый раз обновлять хэш и перекомпилировать.

При этом вы знаете данные, вы можете сказать, как многое, что может повлиять на вас.

Одним из вариантов может быть то, что вы храните данные в базе данных, но затем кэшируете их в HashMap.

1
ответ дан 13 December 2019 в 05:42
поделиться

Если кэш только для чтения, который не обновляется автоматически, все, что вам нужно для вашего приложения, тогда в этом подходе нет ничего плохого.

Есть одно предостережение: если объем данных (включая накладные расходы на объекты Java и HashMap) становится слишком большим, чтобы полностью удерживаться в оперативной памяти, производительность будет быстро и резко снижаться (в 10 000 и более раз). Системы баз данных предназначены для эффективного доступа к данным на диске; HashMap - нет.

3
ответ дан 13 December 2019 в 05:42
поделиться

Ваша идея не так уж и плоха, однако я бы лично выбрал решение для кэширования.

Не обращайте внимания на людей, которые говорят, что вам нужно будет перекомпилировать / перераспределять каждый раз, когда данные изменяются, так как я не думаю, что они понимают, что вы подразумеваете под статическим. то есть они думают, что вы жестко закодировали значения в своем источнике.

1
ответ дан 13 December 2019 в 05:42
поделиться

Проблема с вашим подходом заключается в отсутствии разделения между кодом и данными.

Это приводит к некоторым недостаткам:

  • вы не можете делать резервные копии
  • , вам нужно перекомпилировать / повторно развернуть ваше приложение для изменения данных

Поскольку для этого вам не требуется реляционная база данных, я предлагаю вам использовать встроенную базу данных ключ-значение, например BerkeleyDB , которая также очень быстрая.

1
ответ дан 13 December 2019 в 05:42
поделиться

Сохраните данные в HashMap, если это проще.

Затем вы можете сериализовать копию, используя XStream . Это создаст XML-версию объекта HashMap.

Таким образом, ваше приложение может записать это на диск по мере необходимости, и вы можете отредактировать его вручную и перезагрузить в приложение. Это означает, что у вас есть HashMap и настраиваемое представление на диске, которое вы можете изменить по мере необходимости.

0
ответ дан 13 December 2019 в 05:42
поделиться

Статическое кэширование может работать.

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

0
ответ дан 13 December 2019 в 05:42
поделиться

Нет ничего плохого в этом подходе в целом. Просто убедитесь, что у вас нет прямого доступа к статическому классу, потому что тогда вы создаете « bad singleton ». (Как и глобальная переменная)

Вместо этого введем некоторый механизм регистрации для регистрации этого класса во всех объектах, которые будут его запрашивать. Чем у вас будет «хороший синглтон», и не будет никаких последующих проблем.

public class MyDataClass {
    private MyDataClass() { }
    public static MyDataClass getInstance() {
        if (instance == null) instance = new MyDataClass();
        return instance;
    }
    private static MyDataClass instance = null;
}

public class MyDataProcessor {
    public void registerData(MyDataClass data) { 
       this.data = data;
    }
    public void process() {
        assert(data != null);
        data.getData(...);
    }
    private MyDataClass data;
}

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

1
ответ дан 13 December 2019 в 05:42
поделиться

Стоит ли использовать кеш? Да, если это намного быстрее и вы никогда не хотите обновлять данные, или что это не важно, если кэшированные данные не соответствуют реальным данным.

Вы должны оставить этот доступ за API и скрыть кеширование за абстракцией. Затем вы можете поиграть с разными стратегиями кеширования или полностью отказаться от идеи кеширования без необходимости каждый раз переписывать оставшуюся часть кода.

0
ответ дан 13 December 2019 в 05:42
поделиться

Again, depending on what you do, this could be fine. As long as you had some method of persisting what's in the HashMap or the like in case of server maintainence/shutdown.

All you need is a serialization method. I saw that XStream was mentioned above.

There is also a library called Prevayler. This serializes changes on the fly but lets you keep everything in memory. So in the even of sudden power failure where you don't have time to shutdown properly, this may be of some use.

Experiment with different methods to see what works for you and extract the details away behind a DAO.

0
ответ дан 13 December 2019 в 05:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: