Я знаю, что этот вопрос слишком стар, но я не видел никакой реализации, подобной моей. Эта версия основана на символе преобразования Шварца .
function sortByAttribute(array, ...attrs) {
// generate an array of predicate-objects contains
// property getter, and descending indicator
let predicates = attrs.map(pred => {
let descending = pred.charAt(0) === '-' ? -1 : 1;
pred = pred.replace(/^-/, '');
return {
getter: o => o[pred],
descend: descending
};
});
// schwartzian transform idiom implementation. aka: "decorate-sort-undecorate"
return array.map(item => {
return {
src: item,
compareValues: predicates.map(predicate => predicate.getter(item))
};
})
.sort((o1, o2) => {
let i = -1, result = 0;
while (++i < predicates.length) {
if (o1.compareValues[i] < o2.compareValues[i]) result = -1;
if (o1.compareValues[i] > o2.compareValues[i]) result = 1;
if (result *= predicates[i].descend) break;
}
return result;
})
.map(item => item.src);
}
Вот пример того, как его использовать:
let games = [
{ name: 'Pako', rating: 4.21 },
{ name: 'Hill Climb Racing', rating: 3.88 },
{ name: 'Angry Birds Space', rating: 3.88 },
{ name: 'Badland', rating: 4.33 }
];
// sort by one attribute
console.log(sortByAttribute(games, 'name'));
// sort by mupltiple attributes
console.log(sortByAttribute(games, '-rating', 'name'));
Единственная другая опция состоит в том, чтобы сделать вручную, что много систем RDBMS делают так или иначе...
- Создают новую таблицу
, можно тогда скопировать содержание старой таблицы по блоку за один раз. Всегда будучи осторожным из любого ВСТАВЛЯЕТ/ОБНОВЛЯЕТ/УДАЛЯЕТ на исходной таблице. (Мог управляться триггером. Хотя это вызвало бы замедление, это не блокировка...)
Когда-то законченный, измените имя исходной таблицы, затем измените имя новой таблицы. Предпочтительно в транзакции.
Когда-то законченный, перекомпилируйте любые хранимые процедуры, и т.д. то использование та таблица. Планы выполнения, вероятно, больше не будут действительны.
РЕДАКТИРОВАНИЕ:
Некоторые комментарии были сделаны об этом ограничении, являющемся немного плохим. Таким образом, я думал, что поместил новый взгляд на него для показа, почему это - как это...
Едва ли.
Вы изменяете глубинную структуру таблицы, в конце концов, и это - немного информации, это довольно важно для базовой системы. Вы также (вероятно), перемещаете большую часть данных вокруг по диску.
, Если Вы планируете выполнение этого много, Вы более обеспечены просто дополнение таблицы с "фиктивными" столбцами, которые доступны для будущего использования.
Фиктивные столбцы являются хорошей идеей, если можно предсказать их тип (и сделать их nullable). Проверьте, как Ваши дескрипторы механизма устройства хранения данных аннулируют.
MyISAM заблокирует все, если Вы даже упомянете имя таблицы мимоходом, по телефону, в аэропорту. Это просто делает это...
Однако блокировки не являются действительно настолько большими соглашение; пока Вы не пытаетесь добавить значение по умолчанию для нового столбца к каждой строке, но позволить ему находиться как пустой указатель, и Ваш механизм устройства хранения данных достаточно умен не пойти, пишущий его, необходимо согласиться с блокировкой, которая, как только сохранилось, достаточно долго обновляет метаданные. Если Вы действительно пытаетесь записать новое значение, ну, в общем, Вы - тост.
В целом ответ будет "Нет". Вы изменяете структуру таблицы, которая потенциально потребует большого количества обновлений", и я определенно соглашаюсь с этим. Если Вы будете ожидать делать это часто, то я предложу альтернативу "фиктивным" столбцам - использование VIEW
с вместо таблиц для SELECT
данные луга. IIRC, изменяя определение представления относительно легок, и косвенность посредством представления сделана, когда план запросов компилируется. Расход - то, что необходимо было бы добавить столбец к новой таблице и сделать представление JOIN
в столбце.
, Конечно, это только работает, если можно использовать внешние ключи для выполнения, расположение каскадом удаляет и этажерка. Другая премия - то, что можно составить новую таблицу, содержащую комбинацию данных, и указать на представление на него, не нарушая клиентское использование.
Просто мысль.
Нет. Если Вы используете таблицы MyISAM к моему лучшему пониманию, что они только делают блокировки таблицы - нет никаких рекордных блокировок, они просто пытаются сохранить все гипербыстро через простоту. (Другие таблицы MySQL работают по-другому.) В любом случае можно скопировать таблицу в другую таблицу, изменить его, и затем переключить их, обновив для различий.
Это - такое крупное изменение, что я сомневаюсь, что любой DBMS поддерживал бы его. Это полагало, что преимущество в состоянии сделать это с данными в таблице во-первых.
Так как Вы спросили о других базах данных, вот некоторая информация о Oracle.
Добавление столбца NULL к таблице Oracle является очень быстрой операцией, поскольку оно только обновляет словарь данных. Это содержит монопольную блокировку на таблице в течение очень короткого периода времени. Это будет однако, делать недействительным любые depedant хранимые процедуры, представления, триггеры, и т.д. Они будут перекомпилированы автоматически.
Оттуда при необходимости можно создать индекс с помощью пункта ОНЛАЙН. Снова, только очень короткие блокировки словаря данных. Это считает целую таблицу, ища вещи индексировать, но не блокирует никого при выполнении этого.
, Если необходимо добавить внешний ключ, можно сделать это и заставить Oracle доверять Вам, что данные корректны. Иначе это должно считать целую таблицу и проверить все значения, которые могут быть медленными (создайте свой индекс сначала).
, Если необходимо поместить значение по умолчанию или вычисленное значение в каждую строку нового столбца, необходимо будет выполнить крупное обновление или возможно немного утилиты, которая заполняет новые данные. Это может быть медленно, особенно если строки становятся намного больше и больше не помещаются в их блоки. Блокировка может быть организована во время этого процесса. Так как старый versino Вашего приложения, которое все еще работает, не знает об этом столбце, Вам, возможно, понадобился бы подлый триггер или определить значение по умолчанию.
Оттуда, можно сделать switcharoo на серверах приложений к новой версии кода, и это будет продолжать бежать. Отбросьте свой подлый триггер.
, С другой стороны, можно использовать DBMS_REDEFINITION, который является черным квадратом, разработанным, чтобы сделать этот вид вещи.
Все это - так много беспокойства для тестирования, и т.д. что у нас просто есть начало отключения электричества утра воскресенья каждый раз, когда мы выпускаем основную версию.
Используя плагин Innodb, операторы ALTER TABLE, которые только добавляют или отбрасывают вторичные индексы, могут быть сделаны "быстро", т.е. не восстанавливая таблицу.
Вообще говоря, однако, в MySQL, любой ALTER TABLE включает восстановление всей таблицы, которая может занять очень долгое время (т.е. если таблица имеет полезный объем данных в ней).
действительно необходимо разработать приложение так, чтобы операторы ALTER TABLE не должны были регулярно делаться; Вы, конечно, не хотите ALTER TABLE, сделанного во время нормального выполнения приложения, если Вы не готовы ожидать, или Вы изменяете крошечные таблицы.
Я рекомендовал бы один из двух подходов:
Дизайн Ваши таблицы базы данных с потенциалом изменяется в памяти. Например, я работал с Системами управления контентом, которые изменяют поля данных в содержании регулярно. Вместо того, чтобы создать физическую структуру базы данных для соответствия начальным требованиям поля CMS намного лучше создать в гибкой структуре. В этом случае, с помощью текстового поля блоба (varchar (макс.), например) для содержания гибких данных XML. Это делает структурные изменения очень менее частыми. Структурные изменения могут быть дорогостоящими, таким образом, существует преимущество для стоения здесь также.
Имеют время обслуживания системы. Любой система идет офлайн во время изменений (ежемесячно, и т.д.), и изменений, планируется в течение наименее в большой степени переданного времени дня (3-5am, например). Изменения подготавливаются до производственного развертывания, таким образом, у Вас будет хорошая фиксированная оценка окна времени простоя.
2a. Имейте избыточные серверы, так, чтобы, когда система имеет время простоя, целый сайт не понижался. Это позволило бы Вам "развертывать" свои обновления ступенчатым способом, не удаляя целый сайт.
Опции 2 и 2a не могут быть выполнимыми; они имеют тенденцию быть только для более крупных сайтов/операций. Они - допустимые опции, однако, и я лично использовал все опции, представленные здесь.
Если вы не можете позволить себе простои базы данных при обновлении приложений, вам следует рассмотреть возможность использования двухузлового кластера для обеспечения высокой доступности. При простой настройке репликации вы можете выполнять почти полностью онлайновые структурные изменения, такие как предложенные вами:
Это не всегда просто, но это работает, обычно с нулевым временем простоя! Второй узел не обязательно должен быть только пассивным, он может использоваться для тестирования, ведения статистики или в качестве резервного узла. Если у вас нет инфраструктуры, репликация может быть настроена на одной машине (с двумя экземплярами MySQL).