ترکیب چند جدول سه به بالا

[font="Tahoma"][rtl]

با سلام و خسته نباشید

من چندین جدول دارم که با هم در ارتباط هستند و می خوام اینها رو به هم ارتباط بدم

اگه دو جدول بود با دستور join

اما اگه چند جدول بهترین راهش چیه که فقط با یک دستور sql

اینکار انجام بشه

مثلا:

یه جدول users

profile

access_module_user

post

اینچهار جدول وجود داره و کلید اصلی که بین این چهار جدول مشترک هستش فیلد

user_id

هستش بهترین راه برای ارتباط بین این چهار جدول به چه شکل است؟

[/rtl][/font]

[right][rtl][font="Tahoma"]

سلام

روش ارتباط که join هست اما بهتره برنامه جوری طراحی شه که نیاز نباشه هر چهار جدول رو به هم join بزنیم در هر request

اما اگر به هر دلیل این کار لازم هست، میشه یه view ساخت از ترکیب این چهار تا و فقط ستون های لازم رو هم درش دید، اونوقت با یک select کارتون راه میفته

پ.ن: الان یه سرچ زدم، گویا join زدن تا ۵ تا جدول هم افت شدید کارایی نداره. اما خب به حجم جدول ها و نوع ایندکس ها بستگی داره. میشه از join به همراه cache هم استفاده کرد

[/font][/rtl][/right]

[rtl][font="Tahoma"]در این مورد میشه لطفاً بیشتر توضیح بدید؟[/font][/rtl]

[right][rtl][font="Tahoma"]

حتما!

البته اشاره کنم که منظورم از view، مفهوم دید در پایگاه داده هست و با view که در mvc داریم قاطی نشه

راستش بهتر دیدم جای اینکه خودم چیزی بگم، یک مثال عینی بیارم. در مثال زیر جدول های user و gift و items رو داریم

بعد سناریو اینکه که کاربر ها میتونند آیتم های مختلف رو به هم هدیه بدند. میخوایم یک ویو بسازیم در اون این اطلاعات رو داشته باشیم:

user_from | user_to | gift_name | gift_price

sally | john | Teddy Bear | 10

با روش زیر میتونیم به این view برسیم

و بعد از اون دیگه راحت روی اون فقط select بزنیم و هر بار خودمون اینهمه join رو نزنیم

البته پیش فرض ام با مفهوم view توی پایگاه داده آشنایی دارید :)

[/font][/rtl][/right]




CREATE VIEW GiftsList

AS

SELECT  b.name user_from,

        c.name user_to,

        d.name gift_name,

        d.price gift_price

FROM    gift a

        INNER JOIN users b

            ON a.user_from = b.id

        INNER JOIN users c

            ON a.user_to = c.id

        INNER JOIN items d

            ON a.item = d.id



[font="Tahoma"][rtl]Hestimz ،

جالب بود، ممنونم.

مشکل با همون مفاهیم view دیتابیس هست فک کنم که باید بیشتر روش تحقیق کنم.

واسه ما که تجربی برنامه نویسی رو یاد گرفتیم این مشکلاتم هست ;)

بازهم ممنونم از وقتی که گذاشتی.

[/rtl][/font]

[right][rtl][font="Tahoma"]

آره خودتون از مراجع اصلی بخونید باهاش آشنا شید بهتره، توضیح چند سطری من حتما ناقص خواهد بود و شاید بدتر باعث بدفهمی شه. تکنیک اش رو میشه راحت گفت، اما پیشنهاد من اینه اول یه کم تئوری پشتش رو مطالعه کنید :)

[/font][/rtl][/right]

[font="Tahoma"][rtl]

ممنون دوست عزیز از راهنمایی بسیار خوبتون لطفا لینک آموزشی در این باره با مثال عملی وجود داره که برامون

بفرستید من

در این زمینه مبتدی هستم اگه فارسی باشه بهتره

ممنون

همچنین این کد که گفتید

sql

هستش چطور در yii استفاده بشه و خروجی هاشون رو دریافت کنیم

[/rtl][/font]

[right][rtl][font="Tahoma"]

من مثال ام رو از این لینک پیدا کردم

کسی ک سوال پرسیده زیر سوال اش چهار تا عکس گذاشته که شمای دیتابیس اش هست. اونارو ببینید و عینا بسازید و بعدش کد ای که من تو پست قبلی گذاشتم رو اجرا کنید (با phpMyAdmin که آشنایی دارید؟)

من خودم قبل اینکه پست بگذارم همه رو تست کردم و از صحت اش مطمین ام

بعد اینکه view رو ساختید، یک جدول به لیست جداول شما اضافه میشه، البته آیکون اش با بقیه فرق داره که مشخص میکنه یک view هست

از اینجا به بعد دیگه مثل یک جدول عادی باهاش برخورد کنید. یعنی با استفاده از gii براش مدل بسازید و با ActiveRecord بهش کوئری بزنید

فقط توجه کنید که در حد امکان از update کردن یا delete کردن مقادیر view پرهیز کنید. راستش اصلا نمیدونم mySQL چطوری این رو هندل میکنه، اما از لحاظ تئوری بحث های زیادی ایجاد میکنه. تا دلتون میخواد Select بزنید روش! اگه نیاز به update یا delete دارید مستندات mySQL رو بخونید و از گوگل کمک بگیرید :)

[/font][/rtl][/right]

[font="Tahoma"][rtl]

سلام

ممنون

یه سوال یعنی دوسوال

1- اگه من جدول ویو رو در دیتابیس ساختم و جداول اصلی حذف یا اضافه یا آپدیت بشه جدول ویو هم آپدیت میشه؟

2- بهترین راه ارتباط با دیتابیس به نظرتون کدوم سبک هستش اکتیو رکورد یا مدل دیکه در فریم ورک yii؟

[/rtl][/font]

[right][rtl][font="Tahoma"]

سلام

سوال ۱: بله همه تغییرات در view منعکس میشه و میتونید مطئمن باشید همیشه مقادیرش صحیح هستند. ولی اینکه اگر view رو آپدیت کنید چه بلایی سر جداول اصلی میاد داستان داره و من خودم ازش پرهیز میکنم

سوال ۲: من برای نیازهای عادی از همون اکتیورکورد استفاده میکنم، خیلی انعطاف پذیر هست و سرعت کد زدن رو افزایش میده. البته سعی میکنم کوئری های بهینه بزنم تا از لحاظ کارایی هم بصرفه باشه.

منتها مواقع خاصی که کوئری ها خیلی پیچیده و سنگین هستند و نیاز به join چندین جدول هست و دیتابیس ممکن هست پاسخ های خیلی حجیمی برگردونه، از CDbCommand استفاده میکنم که تا حدی سریعتر هست

ولی بطور کلی از اکتیور رکورد استفاده کنید مگر خلافش ثابت شه

[/font][/rtl][/right]

[font="Tahoma"][rtl]تصاویر ساختاری که گذاشته بود نصفه نیمه بود، نمیدونم چرا کوئریشو نزاشته بود.

من زحمت دوستان رو کم کردم و این کوئری تست است:[/rtl]




--

-- Table structure for table `gifts`

--


CREATE TABLE IF NOT EXISTS `gifts` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `user_from` int(11) NOT NULL,

  `user_to` int(11) NOT NULL,

  `item` int(11) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


-- --------------------------------------------------------


--

-- Table structure for table `items`

--


CREATE TABLE IF NOT EXISTS `items` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(50) NOT NULL,

  `price` varchar(50) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


-- --------------------------------------------------------


--

-- Table structure for table `users`

--


CREATE TABLE IF NOT EXISTS `users` (

  `id` int(11) NOT NULL AUTO_INCREMENT,

  `name` varchar(50) NOT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


-- --------------------------------------------------------



[rtl]کدی هم که در پاسخ ارسال شده بود دو غلط تایپی داشت که من اون رو اصلاح کردم و کد صحیح بدین صورته:[/rtl]


CREATE VIEW GiftsList

AS

SELECT  b.name user_from,

    	c.name user_to,

    	d.name gift_name,

    	d.price gift_price

FROM	gifts a

    	INNER JOIN users b

        	ON a.user_from = b.id

    	INNER JOIN users c

        	ON a.user_to = c.id

    	INNER JOIN items d

        	ON a.item = d.id



[rtl]خب من هم برام سوال بود که این view کجا ذخیره میشه و چطور قابل استفاده، که همونطور که دوستمون اشاره داشتند به شکل بک تیبل در دیتابیس ایجاد میشه که به صورت عادی میشه ازش کوئری گرفت و البته با یک آیکون متفاوت. جالبه!

عکس:

من در پروژه های قبلیم کوئری هایی نوشتم حدود 60 خط، 5 ساب کوئری، 7 جوین که همه با 5 تیبل در یک کوئری درگیر بودند! که اجرای اون هر بار میتونه صحیح نباشه و فکر میکنم باید اون رو به شکل یک view در بیارم و استفاده کنم.

همچنین من در phpmyadmin سعی کردم یک رکورد از view رو حذف کنم. که اجازه نداد و خطای زیر رو داد:[/rtl]


#1395 - Can not delete from join view 'mysql_view.giftslist' 

[rtl]ولی وقتی یک رکورد رو ادیت کردم، علارقم اینکه اخطار زیر رو داد ولی رکورد در view با موفقیت ادیت شد و جالب اینکه رکورد مرتبط در جدول دیگر خودش خودکار به مقدار جدید آپدیت شد![/rtl]


1 row affected.

Note: #1355 View being updated does not have complete key of underlying table in it

[rtl]در نهایت کنجکاوم بفهمم mysql اینکارو چطور و در چه سطحی انجام میده و چقدر انجام اینکار [/font][font="Tahoma"]performance کارو بالا میبره و سرعت اون چقدر تاثیر گذاره.

export یی که phpmyadmin تولید میکنه همچین مثل سایر کوئری های تولید شده نبود و خود این نشون از خاص بودن view داره:[/rtl]


--

-- Structure for view `giftslist`

--


CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`127.0.0.1` SQL SECURITY DEFINER VIEW `giftslist` AS select `b`.`name` AS `user_from`,`c`.`name` AS `user_to`,`d`.`name` AS `gift_name`,`d`.`price` AS `gift_price` from (((`gifts` `a` join `users` `b` on((`a`.`user_from` = `b`.`id`))) join `users` `c` on((`a`.`user_to` = `c`.`id`))) join `items` `d` on((`a`.`item` = `d`.`id`)));



[/font]

[size="2"][font="Tahoma"][right]‫خیلی خیلی ممنون هم از آقای Hestimz و هم آقای کرمعلی زاده که موضوع رو تکمیل کردن[/right][/font][/size]

[right][rtl][font="Tahoma"]

دستت درد نکنه آقا نبی از توضیحات مبسوط و همراه با تصاویرت :)

سوالات خودم راجع به delete و update هم رفع شد.

[/font][/rtl][/right]

[rtl]در انجمن ایران پی اچ پی، بنده با یکی با چند تا از دوستان روی این موضوع بحث هایی داشتیم که به نظرم می تونه برای این سوالتون مفید باشه:

آیا active record خوبه؟؟[/rtl]

[rtl][font="Tahoma"]ظاهراً برای ساب کوئری های تو در تو کار نمیکنه و فقط با جوین ها کار میکنه.

این خطا رو میده:

[/font]

[font="Tahoma"][/rtl]




#1349 - View's SELECT contains a subquery in the FROM clause



[/font]