Теория хранения числа и текста в одном и том же поле SQL - PullRequest
1 голос
/ 02 апреля 2009

у меня есть три стола

Результаты: TestID TestCode Значение

Тесты: TestID TestType SysCodeID

SystemCodes SysCodeID ParentSysCodeID Описание

У меня вопрос, когда пользователь вводит данные в таблицу результатов .

Код форматирования, когда строка получает фокус, меняет поле значения на выпадающий список, если testCode имеет тип SystemList. Раскрывающийся список содержит список всех системных кодов, у которых есть parentyscodeID test.SysCodeID. Когда пользователь выбирает значение в списке, оно переводится в число, которое входит в поле значения.

Тип данных поля Results.Value является целым числом. Я сделал это целое число вместо строки, потому что при составлении отчетов легче выполнять вычисления и сортировку, если это число. Существуют проблемы, если вы помещаете целое / десятичное значение в строковое поле. Кроме того, когда проектировалась система, им нужны были только цифры.

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


Будет ли плохой практикой преобразовывать поле в строку, а затем хранить строки и целые числа в одном поле? Есть разные проблемы, связанные с этим, но я не уверен, что они действительно имеют большое значение.

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

Другой вариант - создать отношение 1-1 к другой таблице, и если пользователь вводит строку в поле значения, он добавляет ее в новую таблицу с ключом числа.

У кого-нибудь есть интересные идеи?

Ответы [ 8 ]

2 голосов
/ 04 апреля 2009

Как насчет обработки Results.Value, как если бы это был числовой ValueCode, который становится внешним ключом, ссылающимся на другую таблицу, которая содержит ValueCode и соответствующую ему строку.

CREATE TABLE ValueCodes
(
    Value     INTEGER NOT NULL PRIMARY KEY,
    Meaning   VARCHAR(32) NOT NULL UNIQUE
);

CREATE TABLE Results
(
   TestID     ...,
   TestCode   ...,
   Value      INTEGER NOT NULL FOREIGN KEY REFERENCES ValueCodes
);

Вы продолжаете хранить целые числа, как и сейчас, но они являются ссылками на ограниченный набор значений в таблице ValueCodes. Большинство существующих значений отображаются в виде целого числа, например 100, со строкой, представляющей то же значение «100». Новые коды могут быть добавлены по мере необходимости.

2 голосов
/ 02 апреля 2009

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

Если они собираются вводить одну из нескольких предварительно заданных строк (например, оценки A, B, C и т. Д.), То создайте таблицу поиска для этих строк, которая сопоставляется с числовыми значениями для сортировки, оценки, усреднения, и т.д.

Если они действительно хотят иметь возможность начинать вводить текст произвольной формы, и вы не можете отговорить их от этого, добавьте еще один столбец в соответствии с параметрами other_entry. Имейте предопределенное значение, которое означает «другое», чтобы поместить в ваш столбец значений. Таким образом, когда вы создаете отчеты, вы можете либо свернуть все эти случайные «другие» значения, либо просто проигнорировать их. Убедитесь, что вы добавили «other» в свою таблицу SystemCodes, чтобы вы могли сохранить внешний ключ между ней и таблицей Results. Если у вас его еще нет, вам обязательно стоит добавить его.

Удачи!

1 голос
/ 04 апреля 2009

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

Похоже, пользователи хотят добавить новые «testCodes». Если это так, почему бы просто не добавить их в существующую таблицу тестовых кодов и сохранить существующий формат.

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

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

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

Том Х. отлично справился со всем остальным.

0 голосов
/ 02 апреля 2009

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

  1. Измените столбец на varchar, а затем вставьте в него числа или текст. Числовая сортировка отстой, но эй, это один столбец.

  2. Иметь столбец varchar для текста и столбец int для числа. Используйте представление, чтобы скрыть различия и при необходимости управлять сортировкой. Вы можете объединить два столбца вместе, если вам все равно, смотрите ли вы на цифры или текст.

0 голосов
/ 02 апреля 2009

Sql Server, по крайней мере, имеет функцию IsNumeric, которую вы можете использовать:

ORDER BY IsNumeric(Results.Value) DESC, 
         CASE WHEN IsNumeric(Results.Value) = 1 THEN Len(Results.Value) ELSE 99 END,
         Results.Value
0 голосов
/ 02 апреля 2009

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

0 голосов
/ 02 апреля 2009

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

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

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

0 голосов
/ 02 апреля 2009

Я думаю, что самый простой способ сделать это - преобразовать Results.Value в "string" (char, varchar, что угодно). Да, это лишает возможности выполнять числовую сортировку (и вы больше не сможете выполнять приведение или преобразование столбца, поскольку текст будет смешан с целочисленными значениями), но я думаю, что любой другой метод будет слишком сложным поддерживать должным образом. (Например, в упомянутом выше случае 1-1 это целочисленное значение является фактическим значением или внешним ключом для таблицы строк? Теперь нам нужен другой столбец, чтобы определить это.)

...