Почему использует '*' для создания представления плохо?

Почему использует '*' для создания представления плохо?

Предположим, что у Вас есть сложное соединение, и все поля могут использоваться где-нибудь.

Затем Вы просто имеете к, выбрал необходимые поля.

SELECT field1, field2 FROM aview WHERE ...

Представление "aview" могло быть SELECT table1.*, table2.* ... FROM table1 INNER JOIN table2 ...

У нас есть проблема, если 2 поля имеют то же имя в table1 и table2.

Действительно ли это - только причина, почему использование '*' в представлении плохо?

С '*', можно использовать представление в другом контексте, потому что информация там.

Что я пропускаю?

С уважением

22
задан David Mulder 26 March 2015 в 22:21
поделиться

12 ответов

Я не думаю, что существует очень в программном обеспечении, которое "просто плохо", но существует много материала, который неправильно используется плохими способами:-)

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

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

Обновление: я не знаю, имел ли OP определенного поставщика базы данных в виду, но теперь ясно, что мой последний комментарий не сохраняется для всех типов. Я обязан user12861 и Jonny Leeds для указания на это, и извините это взято более чем 6 лет для меня для редактирования моего ответа.

37
ответ дан Martin 29 November 2019 в 03:18
поделиться

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

19
ответ дан Anne Porosoff 29 November 2019 в 03:18
поделиться

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

create table temp (i int, j int)
go
create view vtemp as select * from temp
go
insert temp select 1, 1
go
alter table temp add k int
go
insert temp select 1, 1, 1
go
select * from vtemp

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

мне это странное поведение является наиболее неопровержимым доводом для предотвращения выбора * в представлениях.

комментарии учили меня, что MySQL имеет подобное поведение, и Oracle не делает (это узнает об изменениях в таблице). Это несоответствие мне - весь больше причины не использовать выбор * в представлениях.

13
ответ дан user12861 29 November 2019 в 03:18
поделиться

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

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

11
ответ дан Dave 29 November 2019 в 03:18
поделиться

Другая причина, почему" *" опасно, не только в представлениях, но и в запросах, состоит в том, что столбцы могут изменить имя или сменить положение в базовых таблицах. Используя подстановочные средства, что Ваше представление размещает такие изменения легко, не будучи должен быть измененным. Но если Ваши ссылочные столбцы приложения положением в наборе результатов, или если Вы используете динамический язык, который возвращает наборы результатов, включенные именем столбца, Вы могли испытать проблемы, которые трудно отладить.

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

17
ответ дан Bill Karwin 29 November 2019 в 03:18
поделиться

Используя SELECT * в рамках представления не подвергается большой части производительности наверху, если столбцы не будут использоваться вне представления - то оптимизатор оптимизирует их; SELECT * FROM TheView может, возможно, потратить впустую пропускную способность, точно так же, как любое время, Вы вытягиваете больше столбцов через сетевое соединение.

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

Однако по всем причинам, приведенным выше, я очень редко использую SELECT *.

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

4
ответ дан Cade Roux 29 November 2019 в 03:18
поделиться

Это - потому что Вам не всегда нужна каждая переменная, и также удостоверяться, что Вы думаете о том, в чем Вы конкретно нуждаетесь.

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

3
ответ дан Rich Bradshaw 29 November 2019 в 03:18
поделиться

Когда-то давно я создал представление против таблицы в другой базе данных (на том же сервере) с

Select * From dbname..tablename

Тогда однажды, столбец был добавлен к предназначенной таблице. Представление начало возвращать полностью неправильные результаты, пока оно не было повторно развернуто.

<час>

Полностью неправильный: никакие строки.

Это было на SQL-сервере 2000.

я размышляю, что это из-за значений syscolumns, которые получило представление, даже при том, что я использовал *.

3
ответ дан Amy B 29 November 2019 в 03:18
поделиться

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

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

3
ответ дан dkretz 29 November 2019 в 03:18
поделиться

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

2
ответ дан bruno conde 29 November 2019 в 03:18
поделиться

Я думаю, что это зависит от языка, который Вы используете. Я предпочитаю использовать выбор *, когда драйвер языка или DB возвращает dict (Python, Perl, и т.д.) или ассоциативный массив (PHP) результатов. Это делает Ваш код намного легче понять, обращаетесь ли Вы к столбцам по имени вместо как индекс в массиве.

2
ответ дан Brian C. Lane 29 November 2019 в 03:18
поделиться

Никто больше, кажется, не упомянул его, но в SQL Server можно также настроить представление с атрибут schemabinding.

Это предотвращает модификации к любой из базовых таблиц (включая отбрасывание их), который влиял бы на определение представления.

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

2
ответ дан Russ Cam 29 November 2019 в 03:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: