Re[82]: Immutable object
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.12.11 20:22
Оценка:
Здравствуйте, DarkGray, Вы писали:


S>>Вот беда. Ради трехзвенки тебе нужно обязательно ломать идентичность? Что мешает использовать отношение послабже, например эквивалентность по ключу?


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

Головной боли добавляет твоя идентичность с трассами, а не штрихи
Re[76]: Immutable object
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.12.11 20:51
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>>>и опять религиозное мнение без каких-либо выводов из определения.

S>>Ты игнорируешь мои выводы. Зачем мне утруждаться?

DG>мне лишь не нравится, что ты (не говоря уже про Sinclair-а, который кроме букварей вообще больше ничего не читал) часто используешь закон отрицания третьего, который не работает в конструкционной логике.

Прочитал ссылочку про конструктивную математику, теперь отвечу развернуто.
Во-первых — я считаю что Sinclair читал достаточно много, и по субъективным впечатлениям значительно больше меня, а главное, с большим толком. Во-вторых, я считаю что Sinclair достаточно глубоко понимает материал, раскладывает его по полочкам, очень четко выделяет абстракции и их уровни.

DG>а программирование работает в конструкционной логике: потому что интересует возможность реального построения программы из имеющихся ресурсов, а не возможность теоретического существования.


DG>http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BA%D1%82%D0%B8%D0%B2%D0%B8%D0%B7%D0%BC_(%D0%BC%D0%B0%D1%82%D0%B5%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)


Да, существуют объективные причины не считать объекты вечноживущими и пользоваться ограниченным представлением вещественных чисел. Но какие причины для отказа от идентичности в пользу трасс? Причем тут вообще идентичность? Нужна история преобразований объекта — пожалуйста. Версии — отлично. Но без ломания ООП. Чем тебе мешает отличать 2 версии друг от друга по правилам ООП?
То что в программе существует множество объектов, описывающих состояние одной моделируемой сущности в "жизни" — это нормальная ситуация. Считай их журналом. Если мы у больного будем мерить температуру и записывать в тетрадочку, больной от этого не размножится по числу записей, описывающих его состояние!
В общем, я не понимаю. Я могу спокойно думать об иммутабельных объектах как о самостоятельных объектах ООП и у меня от этого не болит голова, как от твоих трасс с затейливой идентичностью.

А приведение типа у тебя так же сохраняет идентичность приведенного с приводимым?
Re[83]: Immutable object
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 19.12.11 20:57
Оценка:
DG>>
DG>>void InversePoints_Inplace(this S_Point[] points)
DG>>{
DG>>  for (int i = 0; i < points.Length; ++i)
DG>>  {
DG>>    p[i].X = -p[i].X;
DG>>    p[i].Y = -p[i].Y;
DG>>  }
DG>>}
S>

S>Это не работает для повторяющихся экземпляров. Суперкомпилятор не знает, будут ли они повторяться. Это библиотечный метод

во-первых, S_Point — это структура, поэтому нет проблемы с повторяющимися экземплярами.
во-вторых, при суперкомпиляции библиотеки и не требуется знание будет повторяться или нет. это задача суперкомпиляции конечного кода.
Re[84]: Immutable object
От: samius Япония http://sams-tricks.blogspot.com
Дата: 19.12.11 21:02
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>>>
DG>>>void InversePoints_Inplace(this S_Point[] points)
DG>>>{
DG>>>  for (int i = 0; i < points.Length; ++i)
DG>>>  {
DG>>>    p[i].X = -p[i].X;
DG>>>    p[i].Y = -p[i].Y;
DG>>>  }
DG>>>}
S>>

S>>Это не работает для повторяющихся экземпляров. Суперкомпилятор не знает, будут ли они повторяться. Это библиотечный метод

DG>во-первых, S_Point — это структура, поэтому нет проблемы с повторяющимися экземплярами.

То что это структура — я упустил.

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

Окей. Так причем тут трассы? Вся работа кода выражается в терминах преобразования и переноса данных без изменения identity.
Re[85]: Immutable object
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 20.12.11 01:48
Оценка:
S> Вся работа кода выражается в терминах преобразования и переноса данных без изменения identity.

почему для функции InversePoints следующий переход верен (из immutable-объектов в mutable)
static class PointHlp
{
  //meta hint: identity(return.Point) == identity(point)
  public static Point Inverse(this Point point)
  {
    if (point == null)
      return null;
    return new Point(x:-point.X, y:-point.Y);
  }
}

public IEnumerable<Point> InversePoints(IEnumerable<Point> points)
{
  foreach (var point in points)
    yield return point.Inverse();
}

void InversePoints_Inplace(this Point[] points)
{
  var _points = new S_Point[points.Length];
  for(int i = 0; i < points.Length; ++i)
  {
    _points[i].X = -points[i].X;
    _points[i].Y = -points[i].Y;
  }

  for(int i = 0; i < points.Length; ++i)
  {
    points[i].X = _points[i].X;
    points[i].Y = _points[i].Y;
  }  
}

а для функции FindNearest переход не верен? в чем отличие? и как его можно формализовать?

//meta hint: identity(return.Point) in (identity(etalonPoints), Point.Zero)
public Point FindNearest(Point point, IEnumerable<Point> etalonPoints)
{
  return etalonPoints.MinElement(etalon => (point.X-etalon.X)*(point.X-etalon.X) + (point.Y-etalon.Y)*(point.Y-etalon.Y)) ?? Point.Zero;
}
public IEnumerable<Point> FindNearest(IEnumerable<Point> points, IEnumerable<Point> etalonPoints)
{
  foreach (var point in points)
    yield return FindNearest(point, etalonPoints);
}

void FindNearest_Inplace(this Point[] points, IEnumerable<Point> etalonPoints)
{
  var _points = new S_Point[points.Length];
  for(int i = 0; i < points.Length; ++i)
  {
    var p = FindNearest(point, etalonPoints);
    _points[i].X = p.X;
    _points[i].Y = p.Y;
  }

  for(int i = 0; i < points.Length; ++i)
  {
    points[i].X = _points[i].X;
    points[i].Y = _points[i].Y;
  }  
}
Re[52]: Immutable object
От: vdimas Россия  
Дата: 20.12.11 04:00
Оценка: 2 (1)
Здравствуйте, Sinclair, Вы писали:

V>>Второй вариант уже перестал быть императивной последовательностью вычислений или еще нет?

S>Вариант — да. Язык — нет, т.к. он позволяет делать и другие "варианты".

Таки тебе эта тема интересна?
ИМХО, нет, не перестал. Ни показанный вариант, ни язык С++ не перестали быть империтивным. Сорри, но это попахивает частовстречающимся на здешних просторах ФП-закидонами, бо от функциональщиков в "запущенной стадии" часто приходится слышать противопоставления императивного и функционального программирования... хотя эти два подхода полностью ортогональны и образуют некое пространство. В общем, именно из-за приписывания иммутабельности только лишь к функциональности я эту тему не люблю. Иммутабельность — это полезная техника сама по себе, "константы" известны еще с первых языков программирования. В моем примере на С++ состояние ВСЕЙ программы изменилось после ввода и инициализации переменных. Порядок инициализации переменных в императивном программировании важен, и этот порядок задается явно. Сам термин "императив" — это приказ, инструкция, соответственно "императивное программирование" — это программирование в терминах последовательности инструкций. Если отбросить растиражированный по интернету вики-мусор, то более грамотное определение такое:

Императивное программирование — технология программирования, характеризующаяся принципом последовательного изменения состояния вычислителя пошаговым образом.

Инициализация переменных — непременное изменение состояния всего вычислителя. Без проблем можно писать императивную программу без всяких ФВП, но полностью в иммутабельном виде, реализуя циклы на рекурсиях. Противоположный полюс от императивного программирования — декларативное программирование, т.е. описание конечного результата, вместо описания способа его получения, а вовсе не функциональное программирование является противоположным полюсом, как постоянно задвигают злобные функциональщики, бо оно точно так же описывает способ вместо результата. Просто в ФП состояние вычислителя недоступно явным образом из ЯП, но оно таки есть, коль язык полный по Тьюрингу.

В общем, принципиальное отличие обсуждаемого РИ и РА — это декларативность vs явные вычисления.


(я чуть перегруппирую, соединив абзацы по одной теме)

V>>А какое нам дело до промежуточных результатов? Разве я хоть раз настаивал хоть на одной подробности реализации? Тем паче, что их много.

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

Таки математический символ не обязан иметь заранее заданное воплощение в какой-либо форме.

S>ОМГ. Ну откуда, откуда это упорство в заблуждениях? http://en.wikipedia.org/wiki/Relational_algebra#Use_of_algebraic_properties_for_query_optimization


Мммм, это должно сойти за док-во, что для конкретной формулы РА порядок вычислений и прочее не важно, не так ли?
И как аргумент дал ссылку на правила раскрытия скобок в рамках этой алгебры? Оригинально. Ну вот у меня есть, допустим, некая логическая схема, и в рамках булевой алгебры я могу как угодно раскрывать скобки или наоборот, выносить составные части выражения за скобки по всем правилам, но каждый раз я буду получать уникальное решение в терминах функциональной схемы, коль дойдет до реализации. Или, программируя некую формулу в компьютере, ты, конечно, можешь раскрывать скобки "на бумаге", но каждый из вариантов будет уникальным, т.е. если входным данным придать физический смысл, то в каждом из случаев промежуточные данные будут иметь разный тип. В итоге, какой бы конкретный вид формулы ты не выбрал для программирования, для нее будет важен порядок вычисления промежуточных аргументов с т.з. их последующего применения именно в этом варианте твоей формулы, пусть даже после 100500 преобразований от предполагаемой исходной формулы.

S>Прочтите весь раздел. Если в нём что-то непонятно, задайте дополнительные вопросы.


Теория без практики мертва. (С)
Ты ведь пока не понимаешь и 50% от того, что говорю, коль приводишь как аргумент такие страницы. Специально переспросил у бывшего одногруппника, с которым поддерживаю связь — он с полуслова понял о чем речь, в отличие от. И я прекрасно вижу — почему. На голой эрудиции так далеко уехать уже не получается, надо или попытаться освоить раздел самостоятельно, или внимать коллегам.

S>>>И есть даже специальные соотношения эквивалентности, которые помогают мне это делать.

V>>На уровне РА отношения эквивалентности есть только у тех операций, которые выразимы через другие...
S>Повторюсь:
S>http://en.wikipedia.org/wiki/Relational_algebra#Use_of_algebraic_properties_for_query_optimization

Ага, повторился.
Это таки каждый раз будет другой набор примитивных операций, для достижения того же результата. Это и есть то, о чем я говорил с самого начала, что любая решаемая задача в терминах РИ имеет в общем случае больше одного решения в терминах РА. Я так думаю, что аналогия булевой алгебры и конкретной схемы реализации некоего логического выражения должна, наконец, подтолкнуть к тому, о чем шла речь. Каждый конкретный бит сигнала-то в конкретной реализованной булевой схеме будет распространяться в общем случае через несколько вентилей, проходя их последовательно в процессе вычислений, хотя все множество поданных на вычислитель бит вычисляется при этом обычно параллельно. Никакой магии.


V>>Полностью совпадает с моими наблюдениями, и никак не коррелирует с "превосходством кластерного индекса" в твоем видении происходящего.

S>Ну как это "не коррелирует". Цитирую:
S>

S>2. В случае наличия кластерного индекса, остальные индексы вместо RID используют ключ кластерного индекса. Поэтому не стоит делать кластерный индекс по длинному ключу, если других индексов много


Тот абзац я скопировал ради последнего предложения:

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

Остальное идет как контекст. Так вот, для случая кластерного индекса на странице содержится вся строка таблицы, т.е. на каждой странице будет меньше значений ключа, поэтому с т.з. быстродействия именно кластерного индекса, чем 'уже (в байтах) таблица, т.е. чем больше записей на каждой странице, тем шустрее поиск по этому ключу. Меньше потребуется просмотреть страниц в случае какого-нить двоичного поиска.


V>>Рекомендацию относительно того, как правильно готовить кластерные индексы, я дал.. ключевое только размер данных таблицы, в которой определен кластерный индекс.

S>Эта рекомендация — полный бред. Размер данных таблицы не играет никакой роли. Вы не понимаете разницы между размером ключа и размером таблицы, что бы вы этим "размером" ни называли? В прошлый раз вы упоминали, что таблица для кластерного индекса должна целиком влезать в ОП — это полный бред. Не должна. Сейчас, вроде бы, подразумеваете, что "размер таблицы" — это размер одного кортежа. Тоже мимо тазика — размер ключа кластерного индекса определяется независимо от размера индексируемых кортежей.

Общий физический размер данных таблицы играет роль для принятия решения — делать уникальный ключ кластерным или нет (для неуникальных индексов кластерный работает хорошо, чуть ниже пройдусь по этой теме). Если кол-во данных в таблице относительно мало, а таблица частоиспользуема, то вполне пойдет кластерный индекс даже для случая, когда строки таблицы относительно широкие. Если вернешься назад, именно об этом с самого начала шла речь, я малость удивляюсь, почему это требуется объяснять.


V>>Насчет блобов (чтобы уже поставить точку), они именно затем и не хранятся вместе с остальными данными таблицы, чтобы обеспечить адекватную работу технологии кластерных индексов.

S>Вы по-прежнему бредите. Кластерным индексам всё равно, есть в таблице блобы, и где они хранятся.

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

S>У вас какое-то радикально неправильное понимание устройства кластерных индексов. Может, вам на примере объяснить?

S>Вот вам таблица

S>
S>create table Person)
S>  id int identity primary key,
S>  passportNumber char(10) not null constraint passportNumber unique,
S>  firstName varchar(max) not null,
S>  lastName  varchar(max) not null,
S>  birthdate datetime not null,
S>  picture varbinary(max), 
S>  // ещё поля на 4 килобайта
S>)
S>

S>Она, вроде бы, широкая. В ней даже блобы есть. Вы что, всерьёз полагаете, что что-то может помешать эффективному использованию кластерного индекса по колонке passportNumber? Нет, ничего.

Это есть объяснение работы кластерного индекса?

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

И вообще, сорри конечно, но у меня закралось предположение, что реальную производительность кластерных индексов vs некластерных ты не измерил ни разу в жизни. Более того, сама мысль, что физически размер строки таблицы "не при чем" когда речь идет об эффективности кластерного индекса (эффективности поиска по нему, надо полагать) порождает еще кое-какие подозрения, но я их оставлю на следующую итерацию. Возможно, что ты просто подзабыл кое-что...


V>>С самого начала упоминалась. Насчет памяти в силе, но объяснять облом. Лучше возьми какую-нить машинку с не очень большим объемом памяти, чтобы не заморачиваться со сверхобъемами, потсавь туда MS SQL и поэкспериментируй с кластерными индексами. Потом с некластерными.

S>В ответ рекомендую открыть SQL Books Online и погрузиться в описание архитектуры кластерных индексов. Я кагбэ все эти вещи на пузе исползал крайне подробно — в том числе и базы больше размера ОП, и прочее.

Давай так, если в MS SQL 2003 и выше что-то кардинально изменилось в плане кластерных индексов, то так и быть, потрачу время на изучение и признаю неправоту (если хотя бы в двух словах обрисуешь, что именно поменялось в плане кластерных индексов). Потому как линейка от 6-ки до MS SQL 2000 была в своё время изучена настолько подробно, насколько это вообще возможно, включая местами исходники. Бо, когда у тебя в кач-ве сервака Пень III 500MHz с двумя гигами оперативки в 99-м году, то работы над эфективностью были малость не те, что сегодня, вернее вовсе не малость, а очень по-взрослому.


V>>Здесь я напомнил кое-что, хотя никто не потрудился обратить внимание, на что намекали... зато могу и впредь спрашивать? Как незамысловато протекает беседа... Ладно, давай завязывать, на что не лень здесь еще отвечу, бо ты уже потратил прилично времени, но потом не обещаю... Конкретно числа в компьютере были напоминанием обыденности ситуации неполного соответствия реализации и модели. Но это нам не мешает использовать матаппарат, до тех пор, пока мы будем находится в области ограничений реализации.

S>Ключевое выделено. У вас, к примеру, понимание области ограничений весьма размыто. Это видно по непониманию, скажем, отличия трёхзначной логики от двузначной, и от последствий этого.

Тот пример, что ты привел, на "последствия" не тянет. Надо просто знать правила boolean test выражений, которые могут быть null. Действий всё-равно только два для твоего примера: включать строку в выходной результат или нет. Третьего для твоего примера не дано, хоть лопни тут, и все правила boolean test приведены в стандарте.


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

S>Откуда возьмётся уменьшение физического объёма сканируемых данных? Вы вообще понимаете, как работают индексы?

Отличный вопрос. Как раз подтверждает мои кое-какие подозрения. Иначе я не могу объяснить, откуда в тебе уверенность, что от размера таблицы и от относительной ширины не зависит сравнительная эффективность одного и того же индекса для случая выполнения его как кластерного или некластерного. Я не знаю, где именно ты лазил, но тестов на производительность ты точно не делал, бо там нехилую разницу легко получить, как раз на твоем примере с passportNumber, и спорить сразу станет не о чем. Еще же можно включить трейс и тупо посмотреть на кол-во сканированных страниц, наконец, для каждого из случаев. Если для некластерного у меня получалось получалось 1-2 страницы, для не самой большой таблицы, то для случае этого же индекса как кластерного — легко десяток-полтора сканированных страниц ради одного значения.


S>Да и для кластерного тоже — самое оно. Вы в качестве ключа для индекса что предполагаете выбирать?


А можно по-русски? Бо индексы бывают еще и неуникальные, т.е. могут не быть альтернативным ключом.


S>Потому что на практике каноничность не интересна. Откройте произвольное приложение, которое работает с базой данных, и поищите, сколько раз встречается select, а сколько раз distinct. Это даст вам примерное представление о доле "РА-совместимых" запросов в типичном SQL.


Сорри, но это уже вовсе безграмотно... Зачем мне distinct при выборе уникальных значений из базы в 3-й НФ? Этот distinct мы уже сократили в уме. А если неуникальные, т.е. не включающие ключи, — то они как раз выбираются для групповых операций, в т.ч. чтобы по ним специально сделать потом distinct. Ну натурально, возвращать серии повторяющихся записей из MS SQL — это верх безграмотности. Такое разве что может быть при исопльзовании базы с какой-нить системой ORM, где сервер используется как хранилище объектов и не особо обременен ни ограничениями целостности, ни прочей реляционной чепухой.

Поэтому вопрос таки в силе, показать пример реального магазина или склада какого-нить, где действительно нужно гнать на клиента последовательность повторяющихся данных без групповых операций над ними. Понимаешь, в чем фишка... Например, даже если физически уникальный ключ на клиента не идет в записи, например в данных для распечатки телефонов сотрудников, у нас априори считается, что записи сотрудников — уникальные, т.е. полная запись о сотруднике БЕЗ основного ключа является альтернативным ключом. Лишь замечу, что такое положение дел наблюдается всегда, когда мы имеем дело с суррогатным ключом, потому он и назван суррогатным, что реальный ключ тоже присутствует в характере прикладных данных.


V>>Если у вас таких "подавляющее большинство", нахрена вам вообще MS SQL? Вместо файловой системы, что ле? По опыту организация магазинов, складов, бухгалтерий и т.д. — не помню ни разу, чтобы мне нужны были данные, не попадающие в ограничения реляционной модели.

S>Это у вас оттого, что вы никогда не задумывались о том, что конкретно подразумевается под "ограничениями реляционной модели".

А конкретное что-то есть, кроме общих фраз?


V>>Над никакой. Что, все СУБД реализуют стандарт SQL-92 целиком и не расширяют своими подробностями?

S>Наоборот. Об этом я и говорю — есть уровень "ISO SQL" (в котором, к слову, даже индексов нет), а есть — уровень "конкретной субд".

Да просто сколько SQL-ей видел, столько раз их заново надо учить, это фактически другие языки, область пересечения диалектов ничтожна, буквально по самым простеньким запросам.


V>>Читал, давно и многократно. Давай конкретную фразу/абзац/не_важно_что, которые должны что-то такое доказать.

S>
S>8.1  <predicate>

S>         Function

S>         Specify a condition that can be evaluated to give a truth value of
S>         true, false, or unknown.
S>


Во-первых, <predicate> — это символ в нотации НФБ, описывающий синтаксис конструкции. Во-вторых, я вполне допускаю определение термина предиката в стандарте для своих нужд. Это как раз в духе моей философии об ограничении применимости артефактов. Вернее о практически отсутствующем ограничении, коль артефакты вводятся в каждую предметную область фактически искусственно.


V>>И причем тут моя голова, есть т.н. boolean test, для строки с where(predicate) если предикат is null должно приниматься какое-то решение, и решение это должно быть двоичное: включать эту строку в результат или нет. Другого не дано.

S>И опять мы посмотрим в стандарт:
S>
S>7.6  <where clause>

S>         Function

S>         Specify a table derived by the application of a <search condition>
S>         to the result of the preceding <from clause>.

S>         Format

S>         <where clause> ::= WHERE <search condition>
S>...
S> General Rules

S>         1) The <search condition> is applied to each row of T. The result
S>            of the <where clause> is a table of those rows of T for which
S>            the result of the <search condition> is true.
S>

S>и далее:
S>
S>8.12  <search condition>

S>         Function

S>         Specify a condition that has the truth value true, false, or
S>         unknown, depending on the result of applying boolean operators
S>         to specified conditions.
S>


Отлично, ЧТД (выделенное).

Итого, в терминах двоичной логики решение принимается так: WHERE <search condition> IS TRUE. Это и есть boolean test. Заметь, не сравнение <search condition> = TRUE, а именно тест IS TRUE.


V>>(Справедливости ради есть тонкости для right/left join, да и то не на всех базах). Конкретно в твоем примере boolen test предиката, который null, означает false.

S>Нет. прочитайте стандарт. Если бы в этом случае "булевый тест" предиката означал false (а стандарт требует вовсе не этого), то NOT() от этого предиката означал бы true.

Это гребанный стыд уже...
NOT — это ключевое слово языка, который разрабатывался чтобы быть максимально близким к человеческому английскому. А что означает NOT в выражении: <expression> IS NOT NULL? Не смущает? Или здесь тоже "троичная логика"?

Таблица истинности для NOT расписана, эта операция определена в языке SQL над доменом {true, false, null}. Но! boolean test производится не над каждой операцией в выражении, а над результатом всего выражения, каким бы составным оно не было.


S>Это называется "закон исключённого третьего", и он не работает в трёхзначной логике.


Это называется boolean test, суть операция приведения значения из одного домена в другой, то бишь банальное приведение типов. Согласен, что семантика конкретно этого случая именно такая, но сам механизм отображения доменов значений гора-а-аздо более универсален. Собственно, реляционная теория этим и занимается. Твоя таблица истинности для boolean test — это и есть обычное реляционное отношение. (масло маслянное, сорри, такова специфика русской терминологии)



V>>А какая СУБД целиком поддерживает стандарт? (уже спрашивал)

S>Зачем целиком? Достаточно поддерживать основные положения. Скажем, в трактовке NULL-ов у MS SQL даже есть опция SET ANSI_NULLS.

Тю, у MS SQL есть, а у MS Access уже нет. В общем, мне эта тема неинтересна, бо она по-факту малопоследовательна, глядя на мн-во реализаций SQL в различных СУБД, чтобы делать какие-то выводы.


S>>>Выдаётся результат, который не соответствует результату в РА.

V>>Почему? Если значение выражения по домену {true, false, null} приводимо к boolean (например через boolean test), то проблема явно надуманна. Тем более, что есть стандарт, где это прописано... В общем, мимо.
S>Что "почему"? Почему результат не соответствует результату в РА? Потому что в РА должно вернуться три кортежа, а в SQL — два. Найдите одно различие.

Ну двойка, заслуженно... Таки задач на РА мы не решали, хотя полно аналогичных тому, как ты привел. Есть домены и заданы ф-ии над ними. Задается в терминах РИ т.н. "корректно определенные формулы", которые идут как условие, необходимо составить решение в терминах РА. Вводишь отношение для преобразования одного домена в другой (таблица истинности для boolean test), добавляешь в исходную схему и расписываешь решение. Это уровень 0 задач. Оставляю как домашнее задание для собственного примера, это элементарно.



V>>Это у тебя в голове они возникают, а не в модели. Действительный пример был с повторяющимися записями в результате, но мне уже интересно, а смысл в них без агрегации? А с агрегацией — вот уже результат соответствует обсуждаемой теме.

S>Я начинаю уставать ходить по кругу. Смысл — в повышении производительности. Если бы этого не было, то никто бы не стал заморачиваться поддержкой мультисетов, и в стандарт бы сразу запихали принудительную агрегацию всех промежуточных результатов.

Еще раз — не всех. Уже из 3-й НФ не факт что так просто получить повторяющиеся данные, которые заведомо не ради группировки или disctinct были получены бо (читать еще раз о физическом смысле суррогатного ключа).

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


V>>Ты хотел сказать "большая часть реальных баз данных поддерживает возможность создания/оперирования данных, не подчиняющихся реляционной теории"? Ну пусть поддерживает, может кому-то и надо... Я за полтора десятка лет работы с SQL во всевозможнейших БД, начиная с самых экзотических еще с середины 90-х, эти возможности не использовал ни разу. Наверно, от недостатка образования.

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

Слова, слова... Даже когда я вводил избыточность ради эффективности, я выходил лишь за рамки 3-й НФ (это водораздел совсем уж грубой избыточности), но не за рамки реляционной теории. Заметь, НФ нужны на стадии изменения данных, а на стадии выборки (коль речь об РА), если считать данные заведомо целостностными, факт соотвествия декомпозии некоей НФ вовсе не принципиален. Предлагаю помедитировать над этим.

V>>Повторюсь для невнимательных: стоит ровно противоположная задача: искать соответствия в аспектах своей частности к некоей известной модели, дабы не изобретать велосипеды.

S>Чтобы искать соответствия, нужно сначала овладеть навыками анализа, т.е. разложения комплексных понятий на элементарные "запчасти".
S>Потом уже можно искать соответствия между этими "запчастями" и "запчастями" из других моделей, а также заниматься "синтезом" — сборкой комплексных понятий из полученных "запчастей".

Угу, осталось сделать всего один шаг и понять, что может кардинальное отличаться терминология в разных предметных областях. Т.е. одни и те же термины в разных координатах могут означать совсем разные понятия и вполне уместен некий перевод одних терминов в другие при переходе из одной модели в другую. Судя по тому замешательству вокруг NOT, сопоставление артефактов моделей оказалось для кое-кого непосильной задачей.


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

S>Для начала нужно вообще иметь понятие о том, что есть рамки такого соответствия. Я уже почти неделю объясняю вам рамки соответствия реальных промышленных СУБД чистой реляционной модели — и несмотря на предположительное наличие у вас опыта и в теории, и на практике, дело идёт со скрипом. Даже когда я вам эти рамки сую под нос в детальных примерах и цитатах, они оказываются трудновоспринимаемыми. А вы говорите — "получаются сами".

Давай так. Ты еще ничего не обяснил. НИЧЕГО. Технические объяснения должны быть верифицируемы, а твой основной аргумент выглядит так: "вы неверно это себе представляете", что невозможно верифицировать. В техническом обсуждении вообще не принципиально, как собеседник что-то себе представляет, это его личные половые трудности. Точка опоры — это терминология и описание статики/динамики предметной области в этих терминах, больше ничего. Остальное — рассуждения в пользу бедных.

Тоже самое касательно ограничений. Я 10-й раз прошу (и знаю, почему) придумать пример, где действительно НАДО выходить за рамки реляционной теории в реальных БД. У меня такое случалось и я знаю когда я это делал — это когда БД исопльзовалась не как реляционнное хранилище. Именно это я собирался продемоснтрировать на абсолютно любом приведенном примере, иначе бы он был сведен к вполне помещающемся в рамки наработок реляционной теории. Обсуждать технические решения вообще интересно само по себе, в отличие от гаданий, насколько "монолитно" (С) что-то у кого-то в голове. Это к мозгоправу, а не сюда.


V>>А уж рассуждать о "способностях" для таких основополагающих примитивов деятельности программиста — ну это низкопробнейший обмен шпильками, что еще сказать... лучше бы опять послал почитать что-нить, иногда люди бывает подкидывают любопытные ссылки...

S>Да без проблем: http://wikipedia.org
S>Ещё рекомендую в гугле делать поиск с define: — это каждый раз, когда вам хочется придумать новый термин.

Ну ты видел в Вики, что одни и те же термины означают разное в разных контекстах? На то они и термины, это обслуживающий аппарат, а не целевой.


V>>То, что тебе дали дополнительный инструмент, разве означает, что первоначальный не нужен?

S>Я не говорю, что он не нужен. Вы спорите сами с собой. Я говорю о том, что существует разница между реляционной моделью у Кодда, расширенной реляционной моделью, и моделью устройства реальной промышленной СУБД.

Приехали... договорились... Да какую бы я реализацию реляционной модели не взял, она будет отличаться от реляционной модели хотя бы потому, что реляционная модель никак не ограничивает свою реализацию. Не понимаешь? Изначально подробностями реализации пренебрегли. Есть, конечно, кое-какие практические наработки и исследования стоимостей операций при разных способах хранения данных, но это сугубо инженерные исследования в конкретных, с т.з. инженерии, условиях, никак не связанных, разумеется, с теорией.

Вопрос на мильон $$, почему в рамках теории реляционных СУБД постоянно упоминается "несогласованное обновление", "ошибки целостности" и т.д. Ведь, с т.з. РА, например, такое невозможно?
ИМХО, ты классически ставишь телегу впереди лошади. Не РА является определяющим в отношениях теории и практики, а наоборот, когда данные УДАЛОСЬ привести в рамки требований РА, можно начинать применять сей аппарат. Это общий алгоритм в любом случае, когда ты хочешь использовать какой-либо матаппарат для своих нужд, не только для реляционных СУБД.

S>Да что тут ломать-то? Независимо от НФ, любая проекция, не включающая в себя primary key, сразу даст вам потенциальные повторы.


Ну, что-то вроде подобного я и ожидал. Поздравляю. Какая именно проекций и зачем она без ключа?
Повторюсь, если ключ был суррогатный, то "потенциальность" повторов очень под вопросом. А если не суррогатный, то я хочу увидеть задачу целиком и убедиться что да, повторы были оправданы. Мне нужен верифицируемый пример.

S>Дистинкт по этим данным конечно же снизит производительность — потому что это group by со всеми вытекающими. В частности, нельзя использовать стриминг и резко возрастает потребность в буферах для промежуточных результатов. При низком коэффициенте повторяемости гораздо эффективнее отложить этот group by до момента, когда он реально нужен.


Господя. MS SQL способен выдавать данные быстрее, даже с учетом всех join и т.д. на современных серваках, чем дотнетный парсер на стороне клиента способен парсить приходящие данные, а потом еще делать ORM. О чем ты тут пытаешься фантазировать?.. Что и как ты меряешь, не поделишься техникой? Тем паче, что возврат более нескольких сотен (грубо) записей из MS SQL всегда просит к себе некоторого внимания, на предмет "а зачем так?".


V>>Ну вот отделил ты операцию "фактор" от остальной РА, например. Поделишься ощущениями?

S>Прекрасные ощущения, а что?

Ну ты же настаивал на отделении "мух от котлет", мне интересно, что ты под этим понимаешь, что есть у тебя и нет у оппонента. Только лишь "прекрасные ощущения"?


V>>Это отрицание возможности применения наработок и опыта по РА для реализации некластерных индексов, например.

S>Какие именно наработки РА вы хотите применить для реализации некластерных индексов?

Уже показывал декомпозицию с вводом системного суррогатного ключа, некоего адреса строки, обеспечивающего O(1) для доступа. Хотя, указанная факторизация лежит вне РА (хоть и совсем рядом), все операции над декомпозицией можно проводить, используя аппарат РА. Исключения составляют неуникальные индексы, которые являются спорной техникой сами по себе, если не являются кластерными при этом. Это я к тому, что делать кластерным внешний ключ бывает намного полезней, чем основной, в плане эффективности. Именно потому, что по основному ключу достается единичная запись, а по внешнему мн-во, поэтому порядок хранения записей начинает играть роль.


V>>Блин, сам же даешь неплохие аналогии, и сам же против них споришь... В 99% случаев ньютоновской за глаза в обычной жизни. А если по какой-то частности не хватает ньютоновской, то берут релятивистскую, но только по этой частности. Так же проще.

S>Не "по какой-то частности", а "для какой-то задачи". И если в задаче нужна релятивистская механика, то будь любезен всю её решать в ней. А не так, что, скажем, скорости ты считаешь релятивистски, а время принимаешь ньютоновским.

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

S>Да у вас куда ни ткни — везде непонимание и заблуждения.


"Прекрасные ощущения"? (С)
Re[53]: Immutable object
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.12.11 12:25
Оценка:
Здравствуйте, vdimas, Вы писали:
V>

V>Императивное программирование — технология программирования, характеризующаяся принципом последовательного изменения состояния вычислителя пошаговым образом.

Ну вот видите, как вы начинаете подтверждать то, что я вам рассказываю. В РА нет никакого последовательного изменения состояния вычислителя.

V>Мммм, это должно сойти за док-во, что для конкретной формулы РА порядок вычислений и прочее не важно, не так ли?

Это должно сойти за доказательство того, что РА не навязывает порядок вычислений.

V>В итоге, какой бы конкретный вид формулы ты не выбрал для программирования, для нее будет важен порядок вычисления промежуточных аргументов с т.з. их последующего применения именно в этом варианте твоей формулы, пусть даже после 100500 преобразований от предполагаемой исходной формулы.

Вы передёргиваете. Да, то, что исполняется реальным query engine — на 100% императивная программа. Там есть вычислитель, есть его состояние. Но между исходной формулой РА и реальным вычислением — бездна. Точно так же я могу сказать, что начав с предиката в РИ я всё равно приду к тому или иному виду физического плана исполнения запроса. Это ничего не говорит о том, что РИ само по себе сколь-нибудь императивно.

V>Ты ведь пока не понимаешь и 50% от того, что говорю, коль приводишь как аргумент такие страницы. Специально переспросил у бывшего одногруппника, с которым поддерживаю связь — он с полуслова понял о чем речь, в отличие от. И я прекрасно вижу — почему. На голой эрудиции так далеко уехать уже не получается, надо или попытаться освоить раздел самостоятельно, или внимать коллегам.

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

V>Остальное идет как контекст. Так вот, для случая кластерного индекса на странице содержится вся строка таблицы, т.е. на каждой странице будет меньше значений ключа, поэтому с т.з. быстродействия именно кластерного индекса, чем 'уже (в байтах) таблица, т.е. чем больше записей на каждой странице, тем шустрее поиск по этому ключу. Меньше потребуется просмотреть страниц в случае какого-нить двоичного поиска.

А, я понял, в чём ваше заблуждение. Вы не понимаете, чем leaf pages кластерного индекса отличаются от non-leaf pages, и поэтому путаете размер ключа кластерного индекса с размером всей таблицы. Для "двоичного поиска" (которым вы, судя по всему, называете операцию index seek) в кластерном индексе конечно же не нужно просматривать "больше" страниц. Точно также просматривается logN.
Вы бы сразу спросили, если в Books Online непонятно написано.

V>Общий физический размер данных таблицы играет роль для принятия решения — делать уникальный ключ кластерным или нет (для неуникальных индексов кластерный работает хорошо, чуть ниже пройдусь по этой теме). Если кол-во данных в таблице относительно мало, а таблица частоиспользуема, то вполне пойдет кластерный индекс даже для случая, когда строки таблицы относительно широкие. Если вернешься назад, именно об этом с самого начала шла речь, я малость удивляюсь, почему это требуется объяснять.

Я три поста назад подробно объяснил, по каким критериям выбирается кластерный индекс. Общий размер данных и ширина таблицы никакого значения не имеют. Если вам это непонятно, то почитайте литературу или спросите.

V>Нет, не все-равно, т.к. данные хранятся вместе с ключами.

Нет, не хранятся. Учите матчасть.

V>Это есть объяснение работы кластерного индекса?

Нет, это мы сейчас ваши заблуждения будем исправлять.
V>Кстати, подходящий пример. Если размер таблицы относительно мал, то кластерный индекс по passportNumber вполне покатит, но если же во много раз больше размеров ОП, то кластерный будет существенно сливать некластерному по тому же полю при выборе одиночных значений.
Ок, пусть таблица во много раз больше "размеров ОП". Вот мы делаем запрос
select * from Person where PassportNumber = @number

Вы всерьёз полагаете, что кластерный индекс по PassportNumber покажет худшую производительность, чем некластерный? Тогда вам ещё много нового предстоит узнать.

V>Давай так, если в MS SQL 2003 и выше что-то кардинально изменилось в плане кластерных индексов,

Да нет, не изменилось. Всё точно так же, как и было в MS SQL Server 7.0.
V>то так и быть, потрачу время на изучение и признаю неправоту (если хотя бы в двух словах обрисуешь, что именно поменялось в плане кластерных индексов). Потому как линейка от 6-ки до MS SQL 2000 была в своё время изучена настолько подробно, насколько это вообще возможно, включая местами исходники.
Исходники? Зачем вам могли понадобиться исходники?
Достаточно штатных инструментов из поставки сервера.

V>Отличный вопрос. Как раз подтверждает мои кое-какие подозрения. Иначе я не могу объяснить, откуда в тебе уверенность, что от размера таблицы и от относительной ширины не зависит сравнительная эффективность одного и того же индекса для случая выполнения его как кластерного или некластерного. Я не знаю, где именно ты лазил, но тестов на производительность ты точно не делал, бо там нехилую разницу легко получить, как раз на твоем примере с passportNumber, и спорить сразу станет не о чем. Еще же можно включить трейс и тупо посмотреть на кол-во сканированных страниц, наконец, для каждого из случаев. Если для некластерного у меня получалось получалось 1-2 страницы, для не самой большой таблицы, то для случае этого же индекса как кластерного — легко десяток-полтора сканированных страниц ради одного значения.

Вы неубедительно врёте. Полтора десятка страниц для индекса, что кластерного, что нет — это нужна очень большая таблица.
Ок, давайте поставим Решаюший Эксперимент.
У вас есть под рукой osql.exe?
Запустите в нём вот такой вот несложный скрипт:

create database TestDB;
GO
use TestDB;
GO
CREATE TABLE [dbo].[Test]
(
    id int identity primary key,
    key1 uniqueidentifier constraint key1 unique clustered,
    key2 uniqueidentifier constraint key2 unique nonclustered,
    padding char(7950) not null default ''
)
GO
CREATE PROCEDURE [dbo].[Initialize]
    @size int
AS
    set nocount on;
    delete from Test;
    declare @i int;
    set @i = 0;
    while @i< @size 
    begin
      declare @key uniqueidentifier;
      set @key = NEWID();
      insert into Test(key1, key2) values(@key, @key);
      set @i = @i + 1;
    end
RETURN 0
GO
set nocount on

declare @pageCount int
set @pageCount = 10 -- укажите здесь количество страниц, которые вы хотите поместить в эту таблицу 
exec Initialize @pageCount 

declare @testid uniqueidentifier
select @testid = key1 from Test where id = cast(round(RAND()*@pageCount , 0, 0) as int)

set statistics io on
select id from Test where key1 = @testid; -- кластерный
select id from Test where key2 = @testid; -- некластерный

GO
use master
drop database TestDB

Если что-то непонятно — спрашивайте.
Можете предсказать количество logical reads для случаев pageCount = 1, 10, 100, 1000, 10000?


V>А можно по-русски? Бо индексы бывают еще и неуникальные, т.е. могут не быть альтернативным ключом.

Ключ индекса — выражение, составленное из столбцов таблицы, которое будет включаться в индекс.

S>>Потому что на практике каноничность не интересна. Откройте произвольное приложение, которое работает с базой данных, и поищите, сколько раз встречается select, а сколько раз distinct. Это даст вам примерное представление о доле "РА-совместимых" запросов в типичном SQL.


V>Сорри, но это уже вовсе безграмотно... Зачем мне distinct при выборе уникальных значений из базы в 3-й НФ? Этот distinct мы уже сократили в уме.

Вы-то сократили, а SQL — нет, не сократил.
V>А если неуникальные, т.е. не включающие ключи, — то они как раз выбираются для групповых операций, в т.ч. чтобы по ним специально сделать потом distinct.
Ключевое слово — потом.

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

Я ничего не говорил про "гнать на клиента". Читайте то, что вам пишут, а не то, что вы себе придумываете.


V>А конкретное что-то есть, кроме общих фраз?

Конкретно — отсутствие дубликатов, двузначная логика.

V>Да просто сколько SQL-ей видел, столько раз их заново надо учить, это фактически другие языки, область пересечения диалектов ничтожна, буквально по самым простеньким запросам.

Прекратите позориться. Есть большое количество кросс-СУБД проектов. Область пересчения диалектов значительно шире, чем чистый SQL-92.

V>>>Читал, давно и многократно. Давай конкретную фразу/абзац/не_важно_что, которые должны что-то такое доказать.

V>Итого, в терминах двоичной логики решение принимается так: WHERE <search condition> IS TRUE. Это и есть boolean test. Заметь, не сравнение <search condition> = TRUE, а именно тест IS TRUE.
Это я и пытаюсь объяснить уже два поста. См. мой пример с юнионом двух селектов.

V>Это гребанный стыд уже...

Да я вижу. Вы никому не говорите, где учились, а то опозорите свой ВУЗ.

V>NOT — это ключевое слово языка, который разрабатывался чтобы быть максимально близким к человеческому английскому.

NOT в данном контексте — это унарная функция, которая реализует в SQL операцию логического отрицания. Ваш К.О.
V>А что означает NOT в выражении: <expression> IS NOT NULL?
Здесь это слово — часть оператора "IS NOT NULL". Конкретно этот оператор никогда не возвращает UNKNOWN.
Никакого отношения к унарной логической функции NOT это не имеет. Чтобы два раза не вставать: Есть ещё NOT BETWEEN, NOT LIKE, и NOT IN.
Кстати, об IS NOT NULL: выражение R IS NOT NULL не эквивалентно выражению NOT R IS NULL.

V>Таблица истинности для NOT расписана, эта операция определена в языке SQL над доменом {true, false, null}.

Вообще-то {true, false, unknown}.
V>Но! boolean test производится не над каждой операцией в выражении, а над результатом всего выражения, каким бы составным оно не было.
И каким образом это опровергает что-то из того, что я сказал?

V>Тю, у MS SQL есть, а у MS Access уже нет. В общем, мне эта тема неинтересна, бо она по-факту малопоследовательна, глядя на мн-во реализаций SQL в различных СУБД, чтобы делать какие-то выводы.

Вы сначала разберитесь в основах, а потом будете делать какие-то выводы.

V>это элементарно.

Удивляет только то, что вы до сих пор не знаете этих общеизвестных фактов из SQL, и мне приходится мучительно их объяснять.

V>В общем, если в ограничения целостности не вбили какое-то правило, то это чаще всего по соображениям эффективности, чтобы сервер не строил ненужный индекс и не делал на каждый чих лишние проверки, а не потому что такого ограничения в предметной области нет.

Ну вот видите — через три поста вы таки понимаете, о чём я говорю. Да, уникальность не вбили в SQL по соображениям эффективности.

V>Угу, осталось сделать всего один шаг и понять, что может кардинальное отличаться терминология в разных предметных областях. Т.е. одни и те же термины в разных координатах могут означать совсем разные понятия и вполне уместен некий перевод одних терминов в другие при переходе из одной модели в другую.

Ну вот видите, как здорово. А ещё на прошлой неделе вам и в голову бы не пришло, что предикат в РА и предикат в SQL вообще могут означать разные понятия.

V>Давай так. Ты еще ничего не обяснил. НИЧЕГО. Технические объяснения должны быть верифицируемы, а твой основной аргумент выглядит так: "вы неверно это себе представляете", что невозможно верифицировать.

Почему? Возможно. Я даю вам задачу, вы её решаете. Если понимаете правильно — ответ совпадает. Если неправильно — ответ не совпадает.

V>Тоже самое касательно ограничений. Я 10-й раз прошу (и знаю, почему) придумать пример, где действительно НАДО выходить за рамки реляционной теории в реальных БД.

Я вам привёл пример выше по топику. Встречный вопрос: зачем создатели SQL так мучились, вводя поддержку мультисетов в язык, если нигде в реальных примерах не нужно выходить за рамки реляционной модели?

V>У меня такое случалось и я знаю когда я это делал — это когда БД исопльзовалась не как реляционнное хранилище.Именно это я собирался продемоснтрировать на абсолютно любом приведенном примере, иначе бы он был сведен к вполне помещающемся в рамки наработок реляционной теории. Обсуждать технические решения вообще интересно само по себе, в отличие от гаданий, насколько "монолитно" (С) что-то у кого-то в голове. Это к мозгоправу, а не сюда.

Мы находимся в форуме, посвящённом мозгоправлению. А я в данный момент играю роль мозгоправа.

V>Приехали... договорились... Да какую бы я реализацию реляционной модели не взял, она будет отличаться от реляционной модели хотя бы потому, что реляционная модель никак не ограничивает свою реализацию. Не понимаешь? Изначально подробностями реализации пренебрегли. Есть, конечно, кое-какие практические наработки и исследования стоимостей операций при разных способах хранения данных, но это сугубо инженерные исследования в конкретных, с т.з. инженерии, условиях, никак не связанных, разумеется, с теорией.

С какой именно теорией? Прочтите учебник по разработке СУБД. Там полно теорий про стоимость операций при разных способах хранения данных.

V>Вопрос на мильон $$, почему в рамках теории реляционных СУБД постоянно упоминается "несогласованное обновление", "ошибки целостности" и т.д. Ведь, с т.з. РА, например, такое невозможно?

Так в рамках практики, или в рамках теории? Вы уже определитесь.

V>ИМХО, ты классически ставишь телегу впереди лошади. Не РА является определяющим в отношениях теории и практики, а наоборот, когда данные УДАЛОСЬ привести в рамки требований РА, можно начинать применять сей аппарат. Это общий алгоритм в любом случае, когда ты хочешь использовать какой-либо матаппарат для своих нужд, не только для реляционных СУБД.



V>Повторюсь, если ключ был суррогатный, то "потенциальность" повторов очень под вопросом. А если не суррогатный, то я хочу увидеть задачу целиком и убедиться что да, повторы были оправданы. Мне нужен верифицируемый пример.

Я привёл вам пример три поста назад.

V>Господя. MS SQL способен выдавать данные быстрее, даже с учетом всех join и т.д. на современных серваках, чем дотнетный парсер на стороне клиента способен парсить приходящие данные, а потом еще делать ORM. О чем ты тут пытаешься фантазировать?..

Я пытаюсь объяснить недалёкому собеседнику, как работают реальные сервера.

V> Что и как ты меряешь, не поделишься техникой? Тем паче, что возврат более нескольких сотен (грубо) записей из MS SQL всегда просит к себе некоторого внимания, на предмет "а зачем так?".

При чём тут "возврат"? Вот я пишу операцию, возвращающую 1 число:
select count(*) from sysobjects, sysobjects, sysobjects, sysobjects

Вы думаете, скорость "возврата результата" будет как-то быстрее, чем дотнетный парсер на стороне клиента? Ну удачи.

V>Уже показывал декомпозицию с вводом системного суррогатного ключа, некоего адреса строки, обеспечивающего O(1) для доступа.

И как это относится к кластерным индексам?

V>Хотя, указанная факторизация лежит вне РА (хоть и совсем рядом), все операции над декомпозицией можно проводить, используя аппарат РА. Исключения составляют неуникальные индексы, которые являются спорной техникой сами по себе, если не являются кластерными при этом. Это я к тому, что делать кластерным внешний ключ бывает намного полезней, чем основной, в плане эффективности. Именно потому, что по основному ключу достается единичная запись, а по внешнему мн-во, поэтому порядок хранения записей начинает играть роль.

Всё зависит не от внешности ключа, а от паттернов доступа. Если я использую запросы типа where primary_key between @low and @high, то несмотря на его уникальность я получу range. Ситуация часто возникает при, скажем, постраничном доступе к данным.
И неуникальные индексы, конечно же, никакой спорной техникой не являются. Это вы просто в предмете не разобрались как следует.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[83]: Immutable object
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.12.11 13:20
Оценка:
Здравствуйте, samius, Вы писали:

DG>>это надо тебя спросить.

S>Я такого не утвреждал. Sinclair?
Я утверждал. Если пройти по логическому пути по убиранию мутабельности из "объектов" Point, то они перестанут быть объектами в смысле ООП. Понятие "один и тот же" для них отпадёт вместе с identity, которая станет не нужна. Вместо этого будет достаточно эквивалентности, определённой как совпадение состояний.
Простой пример на пальцах:
p1 = new Point(1.1);
p2 = p1.Inverse(); // нет, p2 - это никоим образом не "та же самая" точка, что и p1. Рассуждения про "версионную identity" - это антинаучный бред.
p3 = p2.Inverse(); // нет, p3 - это не та же самая точка, что и p2.

Зато p1 эквивалентна p3 в том смысле, что их можно везде использовать взаимозаменяемо, и на все "сообщения" они будут реагировать строго одинаковым образом.
Этот код легко организовать на дотнете, использовав struct Point. Он не будет вести себя как объект, и попытки обмануть природу при помощи боксинга и referenceEquals не покажут ничего интересного.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[78]: Immutable object
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.12.11 13:30
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>результативность не является достаточным критерием для обоснования хорошести решений. как минимум еще выделяют эффективность, экономичность, экологичность. на следующий уровнях еще больше плоскостей выделяется.

Вообще-то в 4Е четвёртая Е — это "этичность", а не экологичность. Но забавно, что вы переносите концепции из теории менеджмента в программирование.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[53]: Immutable object
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.12.11 13:45
Оценка:
Здравствуйте, vdimas, Вы писали:


V>Кстати, подходящий пример. Если размер таблицы относительно мал, то кластерный индекс по passportNumber вполне покатит, но если же во много раз больше размеров ОП, то кластерный будет существенно сливать некластерному по тому же полю при выборе одиночных значений.

V>И вообще, сорри конечно, но у меня закралось предположение, что реальную производительность кластерных индексов vs некластерных ты не измерил ни разу в жизни. Более того, сама мысль, что физически размер строки таблицы "не при чем" когда речь идет об эффективности кластерного индекса (эффективности поиска по нему, надо полагать) порождает еще кое-какие подозрения, но я их оставлю на следующую итерацию. Возможно, что ты просто подзабыл кое-что...

Да, кстати — на основе результатов забега "кластерные против некластерных" на "широкой" таблице, я начинаю испытывать желание проверить ваш рассказ про "мьютекс на создание делегатов". Может быть, он — тоже горячечный бред?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[79]: Immutable object
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 20.12.11 13:58
Оценка:
S>Вообще-то в 4Е четвёртая Е — это "этичность", а не экологичность.

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

> Но забавно, что вы переносите концепции из теории менеджмента в программирование.


программирование — это управляемая деятельность, и соответственно для нее справедливы всё то, о чем говорит менеджмент.
Re[84]: Immutable object
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 20.12.11 13:58
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, samius, Вы писали:


DG>>>это надо тебя спросить.

S>>Я такого не утвреждал. Sinclair?
S>Я утверждал. Если пройти по логическому пути по убиранию мутабельности из "объектов" Point, то они перестанут быть объектами в смысле ООП. Понятие "один и тот же" для них отпадёт вместе с identity, которая станет не нужна. Вместо этого будет достаточно эквивалентности, определённой как совпадение состояний.

достаточно ли только такой эквивалентности, чтобы сделать вывод корректно ли преобразование(при суперкомпиляции, рефакторинге и т.д.) из функции T F(T item) в метод class T{void F()}?


вопрос всё тот же:
почему функцию Inverse корректно преобразовывать в метод Inverse
Point Inverse(this Point point)
{
  return new Point(x:-point.X, y:-point.Y);
}

class Point-штрих
{
  public void Inverse()
  {
    X = -X;
    Y = -Y;
  }
}

а функцию FindNearest нет?
public Point FindNearest(Point point, IEnumerable<Point> etalonPoints)
{
  return etalonPoints.MinElement(etalon => (point.X-etalon.X)*(point.X-etalon.X) + (point.Y-etalon.Y)*(point.Y-etalon.Y)) ?? Point.Zero;
}

class Point-штрих
{
  public void FindNearest(IEnumerable<Point-штрих> etalonPoints)
  {
    var p = etalonPoints.MinElement(etalon => (point.X-etalon.X)*(point.X-etalon.X) + (point.Y-etalon.Y)*(point.Y-etalon.Y)) ?? Point.Zero;
    X = -p.X;
    Y = -p.Y;
  }
}


так же есть и вопрос и про обратное преобразование:
если код содержащий mutable-объект автоматически преобразовывается в код с immutable-объектом, то как меняется функция проверки, что объект тот же самый?
Re[86]: Immutable object
От: samius Япония http://sams-tricks.blogspot.com
Дата: 20.12.11 14:37
Оценка:
Здравствуйте, DarkGray, Вы писали:

S>> Вся работа кода выражается в терминах преобразования и переноса данных без изменения identity.


DG>почему для функции InversePoints следующий переход верен (из immutable-объектов в mutable)

DG>
DG>void InversePoints_Inplace(this Point[] points)
DG>{
DG>  var _points = new S_Point[points.Length];
DG>  for(int i = 0; i < points.Length; ++i)
DG>  {
DG>    _points[i].X = -points[i].X;
DG>    _points[i].Y = -points[i].Y;
DG>  }

DG>  for(int i = 0; i < points.Length; ++i)
DG>  {
DG>    points[i].X = _points[i].X;
DG>    points[i].Y = _points[i].Y;
DG>  }  
DG>}
DG>

DG>а для функции FindNearest переход не верен? в чем отличие? и как его можно формализовать?
Для функции InversePoints ты специфицировал ожидаемый результат. Что при повторении точек каждая из них должна быть инвертирована однажды. А для функции FindNearest ты результат не специфицировал.
Кстати, суперкомпилятор не сможет за тебя это сделать. Максимум на что можно рассчитывать — на код с результатом, эквивалентным некоторому заданному. Да, я не понимаю, что такое "// meta hint", потому скипаю.

DG>
DG>void FindNearest_Inplace(this Point[] points, IEnumerable<Point> etalonPoints)
DG>{
DG>  var _points = new S_Point[points.Length];
DG>  for(int i = 0; i < points.Length; ++i)
DG>  {
DG>    var p = FindNearest(point, etalonPoints);
DG>    _points[i].X = p.X;
DG>    _points[i].Y = p.Y;
DG>  }

DG>  for(int i = 0; i < points.Length; ++i)
DG>  {
DG>    points[i].X = _points[i].X;
DG>    points[i].Y = _points[i].Y;
DG>  }  
DG>}
DG>

не определена переменная "point". если поправить на points[i], то вроде бы все соответствует тому, как я бы определил поведение FindNearest инплейс. Т.е. если даже points и etalonPoints содержат идентичные точки, то ничего дурного не случится, т.к. расчеты проведутся до того как координаты точек перепишутся результирующими значениями.
Re[84]: Immutable object
От: samius Япония http://sams-tricks.blogspot.com
Дата: 20.12.11 15:20
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, samius, Вы писали:


DG>>>это надо тебя спросить.

S>>Я такого не утвреждал. Sinclair?
S>Я утверждал. Если пройти по логическому пути по убиранию мутабельности из "объектов" Point, то они перестанут быть объектами в смысле ООП.
По-моему не так давно вы согласились со мной что они все же не перестают быть объектами в смысле ООП.

S>Понятие "один и тот же" для них отпадёт вместе с identity, которая станет не нужна. Вместо этого будет достаточно эквивалентности, определённой как совпадение состояний.

identity для них не отпадает. Просто она становится по силе эквивалентной эквивалентности. Но это не значит что она отпала.

S>Простой пример на пальцах:

S>
S>p1 = new Point(1.1);
S>p2 = p1.Inverse(); // нет, p2 - это никоим образом не "та же самая" точка, что и p1. Рассуждения про "версионную identity" - это антинаучный бред.
S>p3 = p2.Inverse(); // нет, p3 - это не та же самая точка, что и p2.
S>

и не та же, что и p1 (при ссылочном типе точек).
S>Зато p1 эквивалентна p3 в том смысле, что их можно везде использовать взаимозаменяемо, и на все "сообщения" они будут реагировать строго одинаковым образом.
На все сообщения — да, но сравнение ссылок даст их отличить. Соответственно, вся логика, которая может быть построена на сравнении ссылок, будет чувствительна.
S>Этот код легко организовать на дотнете, использовав struct Point. Он не будет вести себя как объект, и попытки обмануть природу при помощи боксинга и referenceEquals не покажут ничего интересного.
Со struct — да, будет не докопаться.
Re[85]: Immutable object
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.12.11 15:23
Оценка: +1
Здравствуйте, DarkGray, Вы писали:

DG>достаточно ли только такой эквивалентности, чтобы сделать вывод корректно ли преобразование(при суперкомпиляции, рефакторинге и т.д.) из функции T F(T item) в метод class T{void F()}?

В общем случае — нет. Но, к счастью, никто такой задачи и не ставит. Суперкомпиляция, мифы про которую вы тут рассказываете, ничего подобного не делает.
DG>вопрос всё тот же:
DG>почему функцию Inverse корректно преобразовывать в метод Inverse
В общем случае — нет, некорректно. Вы же сами привели пример, где эти реализации не ведут себя одинаково. В конкретном коде это может оказаться корректным. То есть, к примеру, если вы выполнили в первом и втором случае все оптимизации компилятора — инлайнинг, распространение констант, алгебраические преобразования — и получился одинаковый целевой код, то да, преобразование было корректным.

DG>так же есть и вопрос и про обратное преобразование:

DG>если код содержащий mutable-объект автоматически преобразовывается в код с immutable-объектом, то как меняется функция проверки, что объект тот же самый?
Ну, если у вас есть готовый автоматический преобразователь, то напустите его на код, использующий "функцию проверки". Он вам и выдаст результат.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[54]: Immutable object
От: vdimas Россия  
Дата: 20.12.11 16:59
Оценка:
Здравствуйте, Sinclair, Вы писали:

V>>

V>>Императивное программирование — технология программирования, характеризующаяся принципом последовательного изменения состояния вычислителя пошаговым образом.

S>Ну вот видите, как вы начинаете подтверждать то, что я вам рассказываю. В РА нет никакого последовательного изменения состояния вычислителя.

Хе, в С++ тоже нет никакого вычислителя явно. Речь шла об упорядоченности операций. Ты заявлял о том, что последовательность операций не принципиальна. Я отвечал, что для конкретной формулы РА — принципиальна. Ниже чуть подробнее.

V>>Мммм, это должно сойти за док-во, что для конкретной формулы РА порядок вычислений и прочее не важно, не так ли?

S>Это должно сойти за доказательство того, что РА не навязывает порядок вычислений.

Для конкретной выбранной формулы — навязывает еще как. Ты не обратил внимание на характер "раскрытия скобок" по ссылке? Зачастую никакие скобки раскрыть невозможно, особенно когда применяются ф-ии, заданные по условию, например так:
y = f1(f2(f3(f4(x))))
Поэтому, если в некоей формуле-предикате идет ограничение по некоему условию, содержащему некие аттрибуты, то мы не можем произвести преобразование выражения с выносом этого аттрибута. Все показанные преобразования верны только для независимого ограничения по каждому из аттрибутов или когда исходные условия ограничения удается декомпозировать по независимым аттрибутам.

Например, по самой дорогостоящей операции и самому важному преобразованию, обрати внимание по особственной ссылке на "Selection and cross product":

In the above case we break up condition A into conditions B, C and D using the split rules about complex selection conditions, so that A = B C D and B only contains attributes from R, C contains attributes only from P and D contains the part of A that contains attributes from both R and P. Note, that B, C or D are possibly empty.

Т.е. если такое разбиение условия A невозможно, то это преобразование НЕПРИМЕНИМО.

Более того, если декомпозиция находится не в 6-й НФ, т.е. присутствует хоть какая-то избыточность, то у нас есть возможность получить несколько вариантов РА формул для конечного результата, которые НЕ БУДУТ приводимы одни к другим через операции по ссылке, т.к. используют разные отношения в кач-ве аргументов в рамках всей декомпозиции. Я бы назвал этот эффект главным св-вом избыточности. Заметь, на уровне РИ это непринципиально, в отличие от уровня РА, бо РИ игнорирует конкретный вид декомпозиции, важны только зависимости м/у атрибутами в рамках ВСЕЙ схемы данных, но на уровне РА никакие зависимости, кроме ключей, уже не присутствуют.

Итого, переход вот он: это вся схема, по которой проводится декомпозиция под управлением зависимостей (это все НФ), а затем по полученной декомпозиции можно составлять выражения РА для поиска решения, заданного в терминах РИ, причем эти решения будут в общем случае неприводимы один к другому даже через приведенные тобой формулы. Ну а в некоторых частных случаях вполне приводимы, дык ради бога.

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


V>>В итоге, какой бы конкретный вид формулы ты не выбрал для программирования, для нее будет важен порядок вычисления промежуточных аргументов с т.з. их последующего применения именно в этом варианте твоей формулы, пусть даже после 100500 преобразований от предполагаемой исходной формулы.

S>Вы передёргиваете. Да, то, что исполняется реальным query engine — на 100% императивная программа. Там есть вычислитель, есть его состояние. Но между исходной формулой РА и реальным вычислением — бездна. Точно так же я могу сказать, что начав с предиката в РИ я всё равно приду к тому или иному виду физического плана исполнения запроса. Это ничего не говорит о том, что РИ само по себе сколь-нибудь императивно.

РИ конечно не императивно, оно декларативно.

Но твоя т.н. "бездна" — это всего навсего переход от модели таблицы как единого целого к модели ее декомпозиции, учитывающей все индексы по данной таблице. Т.е. нет никакой бездны, это тривиальные преобразования — переход от рассмотрения всей схемы с учетом зависимостей к рассмотрению декомпозиции, проведенной с учетом зависимостей. Далее. Как выбор конкретной формулы управляется оценочным аппаратом сложности — уже обсуждали выше. Но по сути моих возражений: обрати еще раз пристальное внимание, что если взять РАЗНЫЕ исходные отношения в декомпозиции с избыточностью (т.е. если взять любой индекс, а коль он не первичный ключ, он непременно избыточен!!!), то у нас получаются РАЗНЫЕ формулы РА, НЕПРИВОДИМЫЕ один к другому на уровне РА, но приводимые один к другому на уровне ВСЕЙ декомпозиции, т.е. уже на уровне РИ, на уровне полной схемы с учетом зависимостей. Так вот, для случая, когда преобразования условий выборки таки возможна, то весь аппарат РА применим к декомпозиции индекс-таблица. По крайней мере полно обсуждений относительно того, что происходит когда поля в ограничениях запроса есть в выбранном для сканирования индексе, или когда их нет. Это тупое применение наработок РА.

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

S>Пока я не вижу у вас ни позитивных результатов самостоятельного освоения раздела, ни готовности внимать коллегам.


Ох и упорство, достойное лучшего применения.


V>>Остальное идет как контекст. Так вот, для случая кластерного индекса на странице содержится вся строка таблицы, т.е. на каждой странице будет меньше значений ключа, поэтому с т.з. быстродействия именно кластерного индекса, чем 'уже (в байтах) таблица, т.е. чем больше записей на каждой странице, тем шустрее поиск по этому ключу. Меньше потребуется просмотреть страниц в случае какого-нить двоичного поиска.

S>А, я понял, в чём ваше заблуждение. Вы не понимаете, чем leaf pages кластерного индекса отличаются от non-leaf pages, и поэтому путаете размер ключа кластерного индекса с размером всей таблицы. Для "двоичного поиска" (которым вы, судя по всему, называете операцию index seek) в кластерном индексе конечно же не нужно просматривать "больше" страниц. Точно также просматривается logN.

Log2(N) просматривается в любом случае, отличие в том самом К.

S>Вы бы сразу спросили, если в Books Online непонятно написано.


S>Исходники? Зачем вам могли понадобиться исходники?


Понять причины тормозов внешних ключей в MS SQL.
В сравнении с тем же приложением на MS Access тормозило все минимум двухкратно при выборках на той же железке. Когда понял, минимизировал их абсолютный физический размер, изменив в справочниках, где можно, ключи на int8 и int16.

S>Запустите в нём вот такой вот несложный скрипт:


Запущу на досуге, но другой. У тебя два индекса идут по одной таблице, а это не соответствует нашему спору.

V>>Сорри, но это уже вовсе безграмотно... Зачем мне distinct при выборе уникальных значений из базы в 3-й НФ? Этот distinct мы уже сократили в уме.

S>Вы-то сократили, а SQL — нет, не сократил.

И? Результат-то удовлетворяет. Что первично, а что вторично?

V>>А если неуникальные, т.е. не включающие ключи, — то они как раз выбираются для групповых операций, в т.ч. чтобы по ним специально сделать потом distinct.

S>Ключевое слово — потом.

"Потом" — это всё еще в рамках того же выражения.

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

S>Я ничего не говорил про "гнать на клиента". Читайте то, что вам пишут, а не то, что вы себе придумываете.

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


V>>А конкретное что-то есть, кроме общих фраз?

S>Конкретно — отсутствие дубликатов, двузначная логика.

V>>Да просто сколько SQL-ей видел, столько раз их заново надо учить, это фактически другие языки, область пересечения диалектов ничтожна, буквально по самым простеньким запросам.

S>Прекратите позориться. Есть большое количество кросс-СУБД проектов. Область пересчения диалектов значительно шире, чем чистый SQL-92.

Ну, значит мало ты переносил SQL-кода м/у базами. Так и будешь теоретизировать. Более 90% SQL-кода приходится переписывать/исправлять, при переходе с одной СУБД на другую.


V>>>>Читал, давно и многократно. Давай конкретную фразу/абзац/не_важно_что, которые должны что-то такое доказать.

V>>Итого, в терминах двоичной логики решение принимается так: WHERE <search condition> IS TRUE. Это и есть boolean test. Заметь, не сравнение <search condition> = TRUE, а именно тест IS TRUE.
S>Это я и пытаюсь объяснить уже два поста. См. мой пример с юнионом двух селектов.

Ох и юлить...

V>>Это гребанный стыд уже...

S>Да я вижу. Вы никому не говорите, где учились, а то опозорите свой ВУЗ.

V>>NOT — это ключевое слово языка, который разрабатывался чтобы быть максимально близким к человеческому английскому.

S>NOT в данном контексте — это унарная функция, которая реализует в SQL операцию логического отрицания. Ваш К.О.

Не ф-ия а оператор.

V>>А что означает NOT в выражении: <expression> IS NOT NULL?

S>Здесь это слово — часть оператора "IS NOT NULL". Конкретно этот оператор никогда не возвращает UNKNOWN.
S>Никакого отношения к унарной логической функции NOT это не имеет. Чтобы два раза не вставать: Есть ещё NOT BETWEEN, NOT LIKE, и NOT IN.

Это обычный унарный оператор, как при любом другом предикате SQL, поэтому я им тебя не тыкал.

S>Кстати, об IS NOT NULL: выражение R IS NOT NULL не эквивалентно выражению NOT R IS NULL.


Накидал всего... Этого не достаточно для реабилитации, т.к. ты рассуждал о случаях, чтобы аргумент и р-т оператора NOT приводились к boolean, и на этом выводил "троичную логику, которая несовместима с РА", а это бред сивой кобылы. Boolean test выполняется над всем выражением. Мне потребовалось объяснять это 3 поста и заставить тебя сходить по собственной ссылке. Вот что бывает от неумения обобщать знания из разных областей, вот с чем я борюсь тут обычно. Ты не увидел полный аналог м/у операцией приведения типов и реляционным отношением.


V>>Таблица истинности для NOT расписана, эта операция определена в языке SQL над доменом {true, false, null}.

S>Вообще-то {true, false, unknown}.

Oh my God
Можно я таки буду использовать то имя константы, которое использовано во всех виденных мною и тобою в реальной работе СУБД? Тем паче, что это совсем уж непринципиально и понятно как тебе, так и остальным. Спасибо.

V>>Но! boolean test производится не над каждой операцией в выражении, а над результатом всего выражения, каким бы составным оно не было.

S>И каким образом это опровергает что-то из того, что я сказал?

Что нет никакого несоответствие с РА. Есть прописанное в стандарте правило, которое приводит результат выражения из домена { true, false, null} к домену { true, false }. Это преобразование в терминах РА обыгрывается вводом такого отношения и вперед! Твой пример становится очень даже решабельным в терминах РА, хотя ты трижды перед этим утверждал обратное.


V>>Тю, у MS SQL есть, а у MS Access уже нет. В общем, мне эта тема неинтересна, бо она по-факту малопоследовательна, глядя на мн-во реализаций SQL в различных СУБД, чтобы делать какие-то выводы.

S>Вы сначала разберитесь в основах, а потом будете делать какие-то выводы.

Угу, а у вас негров линчуют.


V>>В общем, если в ограничения целостности не вбили какое-то правило, то это чаще всего по соображениям эффективности, чтобы сервер не строил ненужный индекс и не делал на каждый чих лишние проверки, а не потому что такого ограничения в предметной области нет.

S>Ну вот видите — через три поста вы таки понимаете, о чём я говорю. Да, уникальность не вбили в SQL по соображениям эффективности.

Дык, и в реальную модель не всегда вбивают. Понимаешь, не имеет значения, на каком уровне мы обеспечим соответствие данных требованиям реляционной модели. Частично это делается декларативными ср-вами СУБД, частично явно пользовательским кодом внутри триггеров, частично — клиентским приложением (неважно, трехзвенка там с еще одним промежуточным серваком или клиент-сервер). Я уже 10-й раз говорю, что коль такое соответствие получено, то аппарат становится доступен.

Как пример на более низком уровне — ты же сам привел ссылку где прямо написано:

Rules about selection operators play the most important role in query optimization. Selection is an operator that very effectively decreases the number of rows in its operand, so if we manage to move the selections in an expression tree towards the leaves, the internal relations (yielded by subexpressions) will likely shrink.

Это именно то, что происходит при составлении реального алгоритма исполнения запросов. (Физического плана запроса в терминах MS SQL)

S>Ну вот видите, как здорово. А ещё на прошлой неделе вам и в голову бы не пришло, что предикат в РА и предикат в SQL вообще могут означать разные понятия.


Мде, опять юлим. Ню-ню...
Я ведь вижу, что ты всё давно понял, что тебе говорилось изначально... но характер — штука сложная...


V>>Давай так. Ты еще ничего не обяснил. НИЧЕГО. Технические объяснения должны быть верифицируемы, а твой основной аргумент выглядит так: "вы неверно это себе представляете", что невозможно верифицировать.

S>Почему? Возможно. Я даю вам задачу, вы её решаете. Если понимаете правильно — ответ совпадает. Если неправильно — ответ не совпадает.

Твою задачу с where (id=1) ты решил неверно для случая РА. Мне потребовалось 3 поста, чтобы объяснить ошибку в рассуждениях. Просто я вначале подумал, что одного только намека на верное решение будет достаточно. Но посмотри, сколько в итоге было понаписано вокруг банальной операции приведения типов, и даже цитировался стандарт... по тобой же данной ссылке... это просто трындец.


V>>Тоже самое касательно ограничений. Я 10-й раз прошу (и знаю, почему) придумать пример, где действительно НАДО выходить за рамки реляционной теории в реальных БД.

S>Я вам привёл пример выше по топику. Встречный вопрос: зачем создатели SQL так мучились, вводя поддержку мультисетов в язык, если нигде в реальных примерах не нужно выходить за рамки реляционной модели?

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

Я ведь затем и просил примеры, чтобы показать это. Что все эти рассуждения годятся исключительно для осознанного выхода за рамки реляционной модели, что практически всегда скорее исключение, чем правило. Например, хранение иерархических/древовидных данных в СУБД. С одной стороны, они могут находиться в отношениях с другими данными, подчиняющимися реляционной модели, но могут не находиться в этих отношениях сами с собой при популярной наивной реализации, когда невозможно определить через запрос SQL, является ли некий один узел транзитивно родителем другого и с какой вложенностью. Для ответа на этот вопрос надо задавать именно такое отношение, которое хранит эти зависимости, и которое будет избыточным по отношению к наивной схеме, что не всегда удобно. ИМХО, идеальным решением было бы создание СУБД, которая поддерживает как реляционную модель, так и иерархическую, и работу этого хозяйства совместно, тогда вопрос не возникал бы.

V>>У меня такое случалось и я знаю когда я это делал — это когда БД исопльзовалась не как реляционнное хранилище.Именно это я собирался продемоснтрировать на абсолютно любом приведенном примере, иначе бы он был сведен к вполне помещающемся в рамки наработок реляционной теории. Обсуждать технические решения вообще интересно само по себе, в отличие от гаданий, насколько "монолитно" (С) что-то у кого-то в голове. Это к мозгоправу, а не сюда.

S>Мы находимся в форуме, посвящённом мозгоправлению. А я в данный момент играю роль мозгоправа.

Играй себе.


V>>Приехали... договорились... Да какую бы я реализацию реляционной модели не взял, она будет отличаться от реляционной модели хотя бы потому, что реляционная модель никак не ограничивает свою реализацию. Не понимаешь? Изначально подробностями реализации пренебрегли. Есть, конечно, кое-какие практические наработки и исследования стоимостей операций при разных способах хранения данных, но это сугубо инженерные исследования в конкретных, с т.з. инженерии, условиях, никак не связанных, разумеется, с теорией.

S>С какой именно теорией? Прочтите учебник по разработке СУБД. Там полно теорий про стоимость операций при разных способах хранения данных.

О, так уже ты согласился с тем, что на этот счет вполне можно использовать теория реляционных БД? Без всей этой твоей "бездны"?

V>>Вопрос на мильон $$, почему в рамках теории реляционных СУБД постоянно упоминается "несогласованное обновление", "ошибки целостности" и т.д. Ведь, с т.з. РА, например, такое невозможно?

S>Так в рамках практики, или в рамках теории? Вы уже определитесь.

Теории. Просто раздел РА — это всего лишь раздел. А вся теория реляционных БД как раз и посвящена разработке эффективных и непротиворечивых решений.

V>>Повторюсь, если ключ был суррогатный, то "потенциальность" повторов очень под вопросом. А если не суррогатный, то я хочу увидеть задачу целиком и убедиться что да, повторы были оправданы. Мне нужен верифицируемый пример.

S>Я привёл вам пример три поста назад.

Я не увидел постановки задачи для этого решения. Пока нечего верифицировать.


V>>Господя. MS SQL способен выдавать данные быстрее, даже с учетом всех join и т.д. на современных серваках, чем дотнетный парсер на стороне клиента способен парсить приходящие данные, а потом еще делать ORM. О чем ты тут пытаешься фантазировать?..

S>Я пытаюсь объяснить недалёкому собеседнику, как работают реальные сервера.

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

V>> Что и как ты меряешь, не поделишься техникой? Тем паче, что возврат более нескольких сотен (грубо) записей из MS SQL всегда просит к себе некоторого внимания, на предмет "а зачем так?".

S>При чём тут "возврат"? Вот я пишу операцию, возвращающую 1 число:
S>
S>select count(*) from sysobjects, sysobjects, sysobjects, sysobjects
S>

S>Вы думаете, скорость "возврата результата" будет как-то быстрее, чем дотнетный парсер на стороне клиента? Ну удачи.

Можно поинтересоваться, что это была за рефлексия и что она должна была доказать? Этот пример чем-то противоречит РА? Разве кортежи в sysobjects неуникальны? И разве нельзя выполнить оптимизацию конкретно этого запроса по всем правилам РА?


V>>Уже показывал декомпозицию с вводом системного суррогатного ключа, некоего адреса строки, обеспечивающего O(1) для доступа.

S>И как это относится к кластерным индексам?

Почему именно к кластерным? Речь о том, чтобы рассматривать индекс как декомпозицию. Как именно организован переход от индекса к строке за O(1) оставим на совести конкретной СУБД.


V>>Хотя, указанная факторизация лежит вне РА (хоть и совсем рядом), все операции над декомпозицией можно проводить, используя аппарат РА. Исключения составляют неуникальные индексы, которые являются спорной техникой сами по себе, если не являются кластерными при этом. Это я к тому, что делать кластерным внешний ключ бывает намного полезней, чем основной, в плане эффективности. Именно потому, что по основному ключу достается единичная запись, а по внешнему мн-во, поэтому порядок хранения записей начинает играть роль.

S>Всё зависит не от внешности ключа, а от паттернов доступа. Если я использую запросы типа where primary_key between @low and @high, то несмотря на его уникальность я получу range. Ситуация часто возникает при, скажем, постраничном доступе к данным.

OMG, постраничный доступ по первичному ключу?
Нахрена вам вообще реляционная СУБД, не пояснишь?

S>И неуникальные индексы, конечно же, никакой спорной техникой не являются. Это вы просто в предмете не разобрались как следует.


Это ты не разбрался как следует. Практически всегда неуникальный ключ можно обыграть дополнительным отношением, явно отражающим сценарии/потребности прикладной области, и получить больше прибавки к эффективности в итоге, ведь неуникальный индекс тоже сугубо для эффективности вводится. В общем, избыточность ненаказуема в рамках РА, коль удается поддерживать целостность, уже повторял многократно и это тоже своего рода инструмент.
Re[85]: Immutable object
От: Sinclair Россия https://github.com/evilguest/
Дата: 20.12.11 17:58
Оценка: +1
Здравствуйте, samius, Вы писали:
S>По-моему не так давно вы согласились со мной что они все же не перестают быть объектами в смысле ООП.
S>identity для них не отпадает. Просто она становится по силе эквивалентной эквивалентности. Но это не значит что она отпала.
Ок, сдаюсь-сдаюсь.
S>>Простой пример на пальцах:
S>>
S>>p1 = new Point(1.1);
S>>p2 = p1.Inverse(); // нет, p2 - это никоим образом не "та же самая" точка, что и p1. Рассуждения про "версионную identity" - это антинаучный бред.
S>>p3 = p2.Inverse(); // нет, p3 - это не та же самая точка, что и p2.
S>>

S>и не та же, что и p1 (при ссылочном типе точек).
S>>Зато p1 эквивалентна p3 в том смысле, что их можно везде использовать взаимозаменяемо, и на все "сообщения" они будут реагировать строго одинаковым образом.
S>На все сообщения — да, но сравнение ссылок даст их отличить. Соответственно, вся логика, которая может быть построена на сравнении ссылок, будет чувствительна.
Ну вот это как раз артефакт того, что мы хотим работать с ними, как с настоящими объектами. Ссылочная identity тут только вредит.
Именно поэтому я хотел её у них "отобрать" — иначе мы имеем возможность писать некорректный код, который выглядит как корректный.

S>>Этот код легко организовать на дотнете, использовав struct Point. Он не будет вести себя как объект, и попытки обмануть природу при помощи боксинга и referenceEquals не покажут ничего интересного.

S>Со struct — да, будет не докопаться.
Ну то есть докопаться-то можно будет:
if (!object.ReferenceEquals(p1, p3))
  Console.WriteLine("Gosh, identity got all screwed up!");
if (!object.ReferenceEquals(p1, p1))
  Console.WriteLine("Gosh, this is even worse than I expected!");

Но ничего интересного в этом не будет.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[52]: Immutable object
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 20.12.11 18:29
Оценка: +1
S>Эта рекомендация — полный бред. Размер данных таблицы не играет никакой роли.

у вас не зафиксированы до конца термины, чтобы можно было делать такое сильное утверждение.
как минимум не зафиксировано: "о каких запросах вообще идет речь"?
также не зафиксировано как определена операция сравнения для множеств через операцию сравнения для элементов.

зы
например, если запрос можно выполнить на основе лишь некластерного индекса(в частности, например, запрос существования записи) без последующего обращения к кластерному индексу, то поиск по некластерному индексу будет быстрее, и эффект будет тем сильнее проявляться, чем шире таблица.
Re[77]: Immutable object
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 20.12.11 19:22
Оценка:
S>Во-первых — я считаю что Sinclair читал достаточно много, и по субъективным впечатлениям значительно больше меня, а главное, с большим толком. Во-вторых, я считаю что Sinclair достаточно глубоко понимает материал, раскладывает его по полочкам, очень четко выделяет абстракции и их уровни.

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

и не ощущается, что Sinclair это осознает. у тебя оно менее выражено, но тоже достаточно заметно.
Re[87]: Immutable object
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 20.12.11 19:36
Оценка:
S>А для функции FindNearest ты результат не специфицировал.

FindNearest возвращает одну из эталонных точек, и точку Zero, если эталонных точек нет.

> Т.е. если даже points и etalonPoints содержат идентичные точки, то ничего дурного не случится


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