Изменение таблицы SQL Server без последствий - PullRequest
5 голосов
/ 17 июня 2009

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

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

Использование SQL Server 2000 в случае необходимости.

Edit:

К сожалению, столбец не должен принимать значения NULL. Пропустил эту важную информацию действительно

Я думаю, что последствия, которые могут произойти из-за уже внедренных плохих практик,

1) «SELECT *» и привязка к некоторым DataGrid непосредственно к переднему концу. (очень очень низкая вероятность)

2) использование номеров столбцов для выборки из набор данных или данные вместо столбца имена в переднем конце при использовании «SELECT» * "

3) «Вставить в» со значениями последовательно вместо столбца имена.

Каким-то образом, если я смогу сделать так, чтобы столбец принимал значения "NULL" (немного изменяя требования), какое-либо влияние из-за вышеупомянутых пунктов?

Я сомневаюсь в анализе существующего кода, потому что количество SP и функций, использующих эту таблицу, может исчисляться сотнями.

Ответы [ 12 ]

5 голосов
/ 17 июня 2009
  1. Создайте новую таблицу со всеми необходимыми столбцами, назовите ее как хотите.
  2. Создайте представление, назовите его так же, как в старой таблице, и пусть он вернет все столбцы, к которым использовалась старая таблица.
  3. ???
  4. $

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

3 голосов
/ 17 июня 2009

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

Большую часть времени добавление столбца не должно ничего нарушать. Добавление столбца NOT NULL повлияет на все, что делает INSERT, но в противном случае, если ваша база данных спроектирована должным образом, она будет незначительной.


РЕДАКТИРОВАТЬ после обновления NOT NULL

Решение очевидно: добавьте столбец как NULL, обновите данные, включив в него значения, отличные от NULL, для каждой строки, затем измените столбец на NOT NULL.

1 голос
/ 17 июня 2009

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

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

0 голосов
/ 17 июня 2009

Если вы используете alter table и добавляете значение по умолчанию, чтобы все записи получали значение, то это не должно быть слишком плохо, если у вас нет миллионов записей. Не делайте этого через Enterprise Manager (вы никогда не должны изменять таблицы, используя Enterprise Manager, поскольку он полностью воссоздает таблицу, а таблица Alter - нет). Если у вас слишком много записей для автоматического заполнения значения по умолчанию, сначала нужно изменить таблицу, чтобы добавить столбец с нулевыми значениями, а затем обновить столбец до нужных значений (если у вас много записей, вы можете сделать это в баках, а не в блокировании всей таблицы) на основе любых правил, которые вы используете для определения правильного значения для существующих записей. Затем измените таблицу, чтобы столбец не обнулялся, если вы знаете, что нет записей без значения. В настоящее время вы можете рассмотреть значение по умолчанию для любых новых записей, которые не имеют значения.

Будет ли добавление столбца влиять на существующий код. Если разработчики не использовали select * (который никогда не должен использоваться в производственном коде), это не окажет большого влияния, за исключением того, что вы должны добавлять новый столбец для какой-либо цели, и любой код, связанный с этой целью, должен будет обновиться, чтобы включить новый столбец. Так как это столбец, не допускающий значения NULL, необходимо как минимум изменить код для вставки записей и, возможно, код для их обновления (в зависимости от того, будет ли это значение когда-либо обновляться после его установки). также, вероятно, некоторые варианты, которые могут быть затронуты. Код вставки должен быть на месте примерно в то же время, что и изменение, из-за которого столбец не обнуляется, иначе все вставки не будут выполнены, пока вы его не установите. Вы делаете это, делая все это одним большим сценарием.

Если вы думаете, что многие из них будут затронуты, и потребуется время, чтобы разобраться в них всех. создать новую таблицу, включая новый столбец. Заполните его со старого стола. Измените вставки / обновления / удаления, чтобы перейти к новой таблице. Затем удалите старую таблицу и создайте представление с именем старой таблицы, в которой есть только старые столбцы. Сделайте все это в сценариях, чтобы он мог работать на Prod все вместе. Не запускайте его в течение основной части дня, запланируйте его запуск в самые легкие часы использования базы данных.

0 голосов
/ 17 июня 2009

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

Можете ли вы уточнить это?

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

Если вы беспокоитесь о времени блокировки при добавлении столбца в таблицу, добавьте столбцы в конец таблицы (чтобы SQL Server не создавал новую таблицу, скопируйте данные в удалите старую таблицу и переименуйте новую.) почти не влияет на время выполнения

Добавление 50 миллионов строк данных практически не повлияет на время выполнения?

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

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

Важным моментом является то, что не запишет 50 миллионов записей данных. Чтобы продемонстрировать это, просто получим таблицу с 28,176,266 строками ( 4,557 МБ ):

--How many rows in the table
SELECT COUNT(*) FROM BigTable

28176266
(1 row(s) affected)

--How big is the table
EXECUTE sp_spaceused 'BigTable'

name      rows      reserved    data        index_size  unused
--------  --------  ----------  ----------  ----------  ------
BigTable  28176266  4681560 KB  4666984 KB  14536 KB    40 KB

Теперь, когда мы установили, что у меня есть таблица строк 28 миллионов , то есть 4,6 ГБ , давайте добавим столбец к этой таблице:

ALTER TABLE BigTable ADD NewColumn int NULL

Подождите! Вопрос: Сколько времени это займет? Разве это не длинная операция, которая займет блокировку таблицы при создании 28 миллионов записей?

Нет! Давайте посмотрим, сколько времени это займет:

PRINT 'Time before adding the column: '+CONVERT(varchar(50), getdate(), 126)
ALTER TABLE BigTable ADD NewColumn int NULL
PRINT 'Time after adding the column: '+CONVERT(varchar(50), getdate(), 126)

И сколько времени понадобилось, чтобы добавить столбец в таблицу с 28 миллионами строк в 4,6 ГБ?

Time before adding the column: 2012-11-06T14:14:33.493
Time after adding the column: 2012-11-06T14:14:33.503

Ответ: о 10мс

Десять миллисекунды .

0 голосов
/ 17 июня 2009

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

РЕДАКТИРОВАТЬ: Я бы не пытался сохранить один в один, относящиеся к этой релятивности в этой таблице расширений. Я бы вписал строку в таблицу расширений, только если это необходимо, и оставил соединение в представлении. Таким образом, вам не нужно беспокоиться о триггерах или тоннах проверки данных, чтобы убедиться, что таблицы синхронизированы.

0 голосов
/ 17 июня 2009

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

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

0 голосов
/ 17 июня 2009

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

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

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

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

0 голосов
/ 17 июня 2009

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

Иногда мы не можем все исправить, и единственное решение - просто перевязать вещи.

0 голосов
/ 17 июня 2009

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

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