Вот трюк. Позволяет открыть REPL и определить класс:
scala> case class Foo(i: Int)
defined class Foo
и простую функцию, которая работает с этим классом:
scala> def fooToInt(foo: Foo) = foo.i
fooToInt: (foo: Foo)Int
переопределить класс:
scala> case class Foo(i: Int)
defined class Foo
и создать экземпляр:
scala> val foo = Foo(1)
foo: Foo = Foo(1)
Все, что осталось, - вызвать fooToInt
:
scala> fooToInt(foo)
<console>:34: error: type mismatch;
found : Foo(in class $iwC)(in class $iwC)(in class $iwC)(in class $iwC)
required: Foo(in class $iwC)(in class $iwC)(in class $iwC)(in class $iwC)
fooToInt(foo)
Он выглядит знакомым? Еще один трюк, чтобы лучше понять, что происходит:
scala> case class Foo(i: Int)
defined class Foo
scala> val foo = Foo(1)
foo: Foo = Foo(1)
scala> case class Foo(i: Int)
defined class Foo
scala> def fooToInt(foo: Foo) = foo.i
<console>:31: error: reference to Foo is ambiguous;
it is imported twice in the same scope by
import INSTANCE.Foo
and import INSTANCE.Foo
def fooToInt(foo: Foo) = foo.i
. Короче говоря, это ожидаемое, хотя и слегка запутанное поведение, которое возникает из неоднозначных определений, существующих в той же области.
Если вы не хотите периодически :reset
REPL state, вы должны отслеживать созданные вами сущности и, если изменения типов определений, убедитесь, что неопределенные определения не сохраняются (переписывайте вещи, если необходимо), прежде чем продолжить.
GUID по сравнению с Последовательным GUID
А типичный шаблон это должно использовать Гуид в качестве PK для таблиц, но, как отнесено в других обсуждениях (см. Преимущества и недостатки ключей базы данных GUID / UUID ) существуют некоторые проблемы производительности.
Это - типичная последовательность Гуида
проблемы f3818d69-2552-40b7-a403-01a6db4552f7
7ce31615-fafb-42c4-b317-40d21a6a3c60
94732fc7-768e-4cf2-9107-f0953f6795a5
этого вида данных are:<
-
, возможное решение А использует Последовательный Гуид, которые сгенерированы следующим образом:
cc6466f7-1066-11dd-acb6-005056c00008
cc6466f8-1066-11dd-acb6-005056c00008
cc6466f9-1066-11dd-acb6-005056c00008
, Как генерировать их От кода C#:
[DllImport("rpcrt4.dll", SetLastError = true)]
static extern int UuidCreateSequential(out Guid guid);
public static Guid SequentialGuid()
{
const int RPC_S_OK = 0;
Guid g;
if (UuidCreateSequential(out g) != RPC_S_OK)
return Guid.NewGuid();
else
return g;
}
Преимущества
Реальное измерение: Сценарий:
, Лабораторное испытание †“тест SQL Server
VS2008, 10 параллельных пользователей, нет думает время, сравнивает процесса с 600, вставляет в пакет для раскладного стола
Стандартный Гуид
В среднем. Продолжительность процесса: 10.5 секунда
В среднем. Запрос на второй: 54.6
В среднем. Resp. Время: 0.26
Последовательный Гуид
В среднем. Продолжительность процесса: 4.6 секунда
В среднем. Запрос на второй: 87.1
В среднем. Resp. Время: 0.12
Результаты на Oracle (жаль, различный инструмент, используемый для теста) 1.327.613, вставляют на таблице с Гуидом Стандарта гуида PK
, 0.02 секунда. прошедшее время для каждого вставляет, 2.861 секунда. из процессорного времени, общего количества [1 191] 31.049 секунда. истекший
Последовательный Гуид , 0.00 секунда. прошедшее время для каждого вставляет, 1.142 секунда. из процессорного времени, общего количества [1 194] 3.667 секунда. истекший
файл DB последовательное время ожидания чтения передало от [1 195] 6.4 , миллионы ожидают события [1 196] 62.415 секунды к [1 197] 1.2 , миллион ожидает события [1 198] 11.063 секунды.
важно видеть, что весь последовательный гуид может быть предположен, таким образом, это не хорошая идея использовать их, если безопасность является беспокойством, все еще с помощью стандартного гуида.
Для создания это короткий..., если Вы используете Гуид в качестве PK, использует последовательный гуид каждый раз, когда они не пасуются назад и передают от UI, они ускорят операцию и не стоят ничего для реализации.
Я могу отсутствовать, что-то здесь (не стесняйтесь исправлять меня, если я), но я вижу очень мало преимущества в использовании последовательного GUID/UUID для первичных ключей.
точка из использования GUID или UUID по автопостепенному увеличению целых чисел:
, К сожалению, с помощью предложения, Вы проигрываете весь те вещи.
Так, да. Вы сделали GUID лучше. Но в процессе, Вы выбросили почти все причины использовать их во-первых.
, Если Вы действительно хотите улучшить производительность, используйте стандартный автоувеличивающий целочисленный первичный ключ. Это предоставляет все преимущества, которые Вы описали (и больше) будучи лучше, чем 'последовательный гуид' почти каждым способом.
Это, скорее всего, получит downmodded в забвение, поскольку это конкретно не отвечает на Ваш вопрос (который, по-видимому, тщательно обрабатывается так, Вы могли ответить на него сами сразу), но я чувствую, что это - намного более важный момент для повышения.
Если Вы потребность для использования последовательных ГУИДОВ SQL Server 2005 может генерировать их для Вас с эти NEWSEQUENTIALID()
функция.
Однако , так как основное использование ГУИДОВ должно генерировать ключи (или альтернативные ключи), который не может быть предположен (например, чтобы избежать, чтобы люди, передающие предполагаемые ключи, ДОБРАЛИСЬ), я не вижу, насколько применимый они - то, потому что они так легко предполагаются.
От MSDN:
Важный:
, Если конфиденциальность является беспокойством, не используйте эту функцию. Возможно предположить значение следующего сгенерированного GUID и, поэтому, данные доступа, связанные с тем GUID.
Выезд РАСЧЕСКИ Jimmy Nilsson: тип GUID, где многие биты были заменены подобным метке времени значением. Это означает, что РАСЧЕСКИ могут быть заказаны, и, когда используется в качестве результата первичного ключа в меньшем количестве разделений индексной страницы при вставке новых значений.
он в порядке для использования uniqueidentifier (GUID) в качестве Первичного ключа?
Я не вижу, что потребность в уникальных ключах, чтобы быть отгадываемой или нет, передавая их от веб-UI или в некоторой другой части кажется плохой практикой отдельно, и я не вижу, если у Вас есть проблемы безопасности, как использование гуида может улучшить вещи (если это - использование вопроса реальный генератор случайных чисел с помощью надлежащих crypto функций платформы).
другие объекты покрыты моим подходом, последовательный гуид может быть сгенерирован от кода без потребности в доступе DB (также, если только для Windows), и это уникально во времени и пространстве.
И да, вопрос был поставлен с намерением ответа на него, чтобы дать людям, которые выбрали Guids для их PK способ улучшиться, использование базы данных (в моем случае позволил клиентам выдерживать намного более высокую рабочую нагрузку, не имея необходимость изменять серверы).
кажется, что проблемы безопасности много, в этом случае не используйте Последовательный Гуид или, лучше все еще, используйте стандартный Гуид для PK, которые пасуются назад и передают от Вашего UI и последовательного гуида для всего остального. Как всегда нет никакой абсолютной истины, я отредактировал также основной ответ для отражения этого.
Как уже сказал Массимогентилини, производительность можно улучшить при использовании UuidCreateSequential (при создании руководств в коде). Но факт, похоже, отсутствует: SQL Server (по крайней мере, Microsoft SQL 2005/2008) использует ту же функциональность, НО: сравнение / порядок Guids различаются в .NET и на SQL Server, что все равно вызовет больше операций ввода-вывода, потому что гиды будут заказаны неправильно. Чтобы правильно сгенерировать направляющие, упорядоченные для сервера sql (упорядочивание), вам необходимо сделать следующее (см. сравнение подробности):
[System.Runtime.InteropServices.DllImport("rpcrt4.dll", SetLastError = true)]
static extern int UuidCreateSequential(byte[] buffer);
static Guid NewSequentialGuid() {
byte[] raw = new byte[16];
if (UuidCreateSequential(raw) != 0)
throw new System.ComponentModel.Win32Exception(System.Runtime.InteropServices.Marshal.GetLastWin32Error());
byte[] fix = new byte[16];
// reverse 0..3
fix[0x0] = raw[0x3];
fix[0x1] = raw[0x2];
fix[0x2] = raw[0x1];
fix[0x3] = raw[0x0];
// reverse 4 & 5
fix[0x4] = raw[0x5];
fix[0x5] = raw[0x4];
// reverse 6 & 7
fix[0x6] = raw[0x7];
fix[0x7] = raw[0x6];
// all other are unchanged
fix[0x8] = raw[0x8];
fix[0x9] = raw[0x9];
fix[0xA] = raw[0xA];
fix[0xB] = raw[0xB];
fix[0xC] = raw[0xC];
fix[0xD] = raw[0xD];
fix[0xE] = raw[0xE];
fix[0xF] = raw[0xF];
return new Guid(fix);
}
или эта ссылка или эта ссылка .